Table cell change to date and time picker

I want to be able to select time from the perspective table.
The table get data from a dataset.


it's setup as per the following post.

the table has been setup nicely.
But for the viewparams setup, how do I point this value to the value of this row at this column?
or do I need to write script to get the row index, then assign the value of this Value[row][column] to this param?

I searched the forum, but haven't found the answer yet.

Regards

Change the name of the view parameter to value. Do not configure it in columns, as it is automatic.

1 Like

Thank you for the reply.

I have now configured to value, now I can see the different time values of each row.

Then I changed params of the value so I can read and write, but somehow I cannot change values from the table. If I change directly from the dataset, the new values can be updated to the table.

  1. component params value setup.
  2. time picker value binding. bidirectional is already selected.
  3. the table configuration of the columns. I tried with or without the viewParams setting of the value tag, neither way works.

when changing the time by clicking the up/down arrow, 1 sec later, the value changed back.
do I need to setup any action trigger each time I change the value?

Thanks.

You need to message to the containing view so it can change the table data.

1 Like

There are several implicit parameters for the subviews. See:

https://forum.inductiveautomation.com/t/perspective-table-dynamic-column-viewparams-per-row/34657/2

or
https://www.docs.inductiveautomation.com/docs/8.1/appendix/components/perspective-components/perspective-display-palette/perspective-table/displaying-a-subview-in-a-table-row#:~:text=Summary%20of%20Subviews%E2%80%8B,a%20value%20under%20this%20object.

So your viewParams would not include the element ‘time’.

You don’t even have to add the implicit parameters in the columns viewParams configuration.

You DO have to declare them in the embedded view with the correct name or you won’t have a property value to reference them.

embedded_view.params: {

value: null, # The value of the row from the selected column arrives here. The param property name must be ‘value’.

rowData: null, # Include this if you need to refer to data from other columns.

rowIndex: 0, # Include this if you need the index into the full dataset.

row: 0 # Include this if you need the index into the filtered dataset.

}

Hopefully, that answers your question. Happy programming!

1 Like

Is the param bidirectional?

Thanks all for the comments.

Here's the working solution.

  1. setup a time picker component.
  2. configure these parameters.

    column, columnIndex, row, rowIndex and value, are the default params passed from the table to the component. As I have two time picker, one for start time, one for end time. so I create a new tag "tag_name" to record which time it is.
  3. the time picker value is bound to the view.params.value.

    the change script of the value binding is:
def valueChanged(self, previousValue, currentValue, origin, missedEvents):
		value = currentValue.value
		if value is not None:
			if 'Binding' not in str(origin):
				msg = 'UpdateRow'
				rowIndex = self.view.params.rowIndex
				tag_name = self.view.params.tag_name
				payload =	{
							'value'	: value,
							'rowIndex': rowIndex,
							'tag_name': tag_name
							}
				system.perspective.sendMessage(msg, payload)

once configured, whenever the time picker value is changes, it will send a message.
4. this is the table configuration of the time picker.
Processing: image.png…
5. this is the message handler script of the table.

def onMessageReceived(self, payload):

	value = payload['value']
	rowIndex = int(payload['rowIndex'])
	tag_name = str(payload['tag_name'])
	tagPath = "[default]Site_Control/ds_csp_1"
	dataset = system.tag.readBlocking(tagPath)[0].value
	system.tag.write(tagPath, system.dataset.setValue(dataset, rowIndex, tag_name, value))

In summary, the basic data flow is:

  1. operator change time picker value.
  2. the following values are sent from the table component to the embedded time picker component.
    column, columnIndex, row, rowIndex and value
  3. the time picker component detects the value change, then it executes the message script.
  4. the table received the message handler, it executes the logic to write to the table binding tag
  5. the updated tag is bound to the table, then the table is refreshed with the new value.

as Phil mentioned, you need to create message to send back the updated value.

The following script converts pyDataset to dataset.
I found it handy sometimes.

def pyds_to_ds(value):
	   headers = system.dataset.getColumnHeaders(value)
	   newData=[]
	   for rowIndex in range(value.rowCount):
	       	row = [value.getValueAt(rowIndex,col) for col in range(value.columnCount)]
	       	newData.append(row)
	   return system.dataset.toDataSet(headers,newData)