[Table] propertyName == 'SelectedRow'

Hello,

i'm facing an issue, again:

I'm trying to run a script in a 'Table' component with the event handler 'onPropertyChange', and i'm having trouble because sometimes the table returns me 3 changes on propertyName == "selectedRow" even if i changed it just once.

Here is what i did:

I've create a Memory Dataset TAG which is linked to a TABLE.data, in order to display it's value.
I've created a button that adds a row into this Dataset TAG.
If you click the button, it has to add a new line into the Dataset TAG, and then, the button, has to select the row it just inserted.

Meanwhile, because the 'selectedRow' changed, the table runs the 'onPropertyChange' script, that have to check if the event.propertyName "selectedRow" has changed and launch a function.

What i'm facing:

While adding the first row to the dataset TAG and selecting the new row into the Table, it works as expected.
If i add the second, third, fourth, etc..it adds the row and it select it, but the 'onPropertyChange' script run 3 times instead of 1, because it get that the "Selected" row changed from -1 to 0, from 0 to 1 and from 1 to 2, so my function runs 3 times instead of 1.

Below, you'll find the output of the console, where i printed both the result of the function and the selectedRow .newValue and the message that it's inside of my function "aggiungiStep()"

Button script:

//Getting dataset from the table
Dataset = event.source.parent.getComponent('Table').data

// Add new row to the dataset
Row = ["Test"]
New_Dataset = system.dataset.addRow(Dataset,Row)

// Get the new line index
Row_Select = New_Dataset.rowCount - 1

// Write the new dataset to the TAG
system.tag.write('Local/test',New_Dataset)

Table script:

// Check if .data lenght changed and select the row based on some values
if event.propertyName == "data":
Programma_DS = event.source.data
Riga_Sel = event.source.selectedRow
Old_DS = event.oldValue.rowCount
New_DS = event.newValue.rowCount
if Old_DS < New_DS:
event.source.selectedRow = Riga_Sel + 1
else:
if New_DS >= 1:
event.source.selectedRow = Riga_Sel -1
else:
event.source.selectedRow = -1

// function which is called if selectedRow changed
def aggiungiStep():
print "aggiungiStep()"

// event selectedRow
if event.propertyName == "selectedRow":
print event.newValue
aggiungiStep()

The trouble you are facing is that setting the ‘data’ property in any way (via the tag binding in your case) requires the table to deselect the row, install the new data, and then re-select the previous row. So the row gets set to -1 (deselected), then back to its previous value. These occur synchronously (nested inside the setData() operation), and cannot be suppressed. I’ve always handled this by placing the desired selection into a custom property just before assigning to data. Then, in a separate if block looking for the change to data, set the selected row from the custom property, resetting the custom property back to -1 at that point. And ignoring the custom property when -1.

1 Like

Thanks to your tips, i’ve got it to work.

Will this method handle also the initial TAG change?

This event (-1,0,-1) occurs also in element’s property binded with TAGs, but in a different way.

  • Run client app
  • Open a desired page
  • Ignition asks for TAGs values to PLC, meanwhile it empties the old selectedLabel values by setting it to EMPTY
  • Element detects changes
  • When the TAG’s load is complete, it changes the selectedLabel back to the PLC current value.

This is the same trouble we were facing on the selectedRow.

Is there a way to skip it? Because i would like to fire a “selectedLabel” event when a Dropdown list has changed.

I appreciate your help @PTURMEL!

I do use a custom property to distiguish value sources in such cases, but it’s not really the same as the first question. Simply, bind your tag to a “raw” custom property on the dropdown, then bind the dropdown’s selectedValue to the custom property, but unidirectionally. Then use a propertyChange event something like this:

if event.propertyName=='selectedValue':
	# raw and editable values will be equal if this event was caused by a tag change or has
	# already been handled.
	if event.newValue != event.source.rawTagValue:
		# do something on user selection from the dropdown.

		# the following makes them equal again, and if the raw binding is bidirectional,
		# writes back to the PLC.
		event.source.rawTagValue = event.newValue
1 Like