Pretty simple code does not work and IDK why

Hello,

I have a powertable on the form in the window called XYZ_Images. This powertable does have a DB table as a source. In this table, records are being written (sometimes few per Minute, sometimes no record written for half an hour). The SELECT ORDERs BY timestamp descending (most recent row should be the first in the table). I’d like to refresh the powertable with client script every 10 seconds and in case new record has been added, I’d like to select programatically first row. I’ve done this:

def refreshList():
	try:
		rowcountBeforeRefresh =  system.gui.getWindow('XYZ_Images').getRootContainer().getComponent('Power Table').data.rowCount
		system.db.refresh(system.gui.getWindow('XYZ_Images').getRootContainer().getComponent('Power Table'),'data')
		rowcountAfterRefresh = system.gui.getWindow('XYZ_Images').getRootContainer().getComponent('Power Table').data.rowCount
		if rowcountBeforeRefresh < rowcountAfterRefresh:
			 system.gui.getWindow('XYZ_Images').getRootContainer().getComponent('Power Table').selectedRow = 0	
	except:
		pass 

The table is being refreshed flawlessly, the first row is not selected though.

Thank you in advance for the hints.

def refreshList():
	try:
		rowcountBeforeRefresh =  system.gui.getWindow('XYZ_Images').getRootContainer().getComponent('Power Table').data.rowCount
		system.db.refresh(system.gui.getWindow('XYZ_Images').getRootContainer().getComponent('Power Table'),'data')
		rowcountAfterRefresh = system.gui.getWindow('XYZ_Images').getRootContainer().getComponent('Power Table').data.rowCount
		if rowcountBeforeRefresh < rowcountAfterRefresh:
			def later(target=system.gui.getWindow('XYZ_Images').getRootContainer().getComponent('Power Table'))
				target.selectedRow = 0
			system.util.invokeLater(later)
	except:
		pass

It’s possible that the selectedRow modification is happening before the table repopulates with data - try wrapping it in an invokeLater so that it happens after the rest of the processing on the event dispatch thread.

https://docs.inductiveautomation.com/display/DOC79/system.util.invokeLater

1 Like

Nope, it does not work anyway. The behavior is still the same new record is being loaded, but it is not selected programatically. However, after discussing this feature with the users, they came to concluson they don't need it, therefore I don't need the solution to this problem. However, Thank you Paul for the effort. Take care.

I’ll give a solution anyway. That way, if the customer decides they want it after all, you have it in your back pocket. :wink:

  • On the Power Table, add a custom property: tableLength

  • Set tableLength to the following expression (this one assumes the table is in the root container):
    len({Root Container.Power Table.data})

  • Use a propertyChange script on the PowerTable to monitor tableLength:

if event.propertyName == 'TableLength':
  if event.newValue > event.oldValue:
    event.source.selectedRow = 0  

1 Like

Hello Jordan,

that’s a pretty cool approach. I’m an Ignition-newbie, I would not think of that ;-). Thank you, take care.

I recall playing with these events and noted that assignment to data would generate events on both data and selectedRow, like so: -1 => selectedRow, newdata => data, previously selected row => selectedRow. So to change the selected row on a data event, the assignment had to be deferred until after the internal reset of the selected row back to its previous value. I haven’t investigated the event order for the Table lately, but you might want to put some print statements in your propertyChange script to see what’s happening, and in what order.

2 Likes