Trying to have a number of cells in a perspective table be editable by the user and write back to the data property of the table. The data property is bound to a view custom property. My understanding from several other threads here is that it will not write back by default, a script must be triggered the onEditCell Commit event.
Error running action 'component.onEditCellCommit' on plc-import@C/root/TabContainer/Alert Config Container/Table: Traceback (most recent call last): File "<function:runAction>", line 2, in runAction TypeError: com.inductiveautomation.perspective.gateway.script.PropertyTreeScriptWrapper$ArrayWrapper indices must be integers
Every time the error is because of the column name being a string instead of an integer. event[‘column’] is giving the “field” name under the column config.
I’m almost certain I’m not understanding and abusing the datatypes as I’m passing data between tables and view properties, then to other tables. The field value of “column_1” is not something I chose, but how I was able to map the column config to the unnamed columns in the data property. Data property looks like:
Short version: My data property being a list of lists and how event.column is always returning a string name was the cause, I decided it would be much better practice to change how I was generating this data to instead be a dictionary with meaningful names. In addition to being more descriptive, I could now use the string event.value to update the cell solving the problem.
Longer version: I still think event.column should probably return an int column number when the data is a list of lists. I did a bit more experimentation…
Created this simple table to play with, mimicking my list of lists data property I generate in scripting. First notice the column_# headers, these were not created by me but automatically assigned. There is nothing configured under the columns property of the table. These identifiers must be what Ignition is using to track the columns - they are what you need to put in the field column if you create an object under columns property to configure the column. This string naming is also used for the selection.selectedColumn property of the table.
This is odd to me since someone setting up a table in this way wouldn’t have any context of that “column_#” naming, especially if they have headers hidden on the table. This brought me to the question of when will event.column ever return an integer if not in this case. The event script comments claim it can be in int.
When data is an array of dictionaries it make perfect sense to return the key name since that is what would be used to work with the dictionary. I tried manually creating something in the data property that would return and int but couldn’t for any choice of Value, Object, or Array. Obviously values wouldn’t make sense as the data wouldn’t have a column dimension. I tried creating a new object under data and creating elements under it with integer names to see if that would return the numbers but it can’t be created that way.
Even creating an array of arrays (had to create an element in each array to display anything) still uses the “column_#” string:
Thinking about the data structure a bit more, it seems like my list of lists was actually converted to an array of dictionaries by the binding process where they keys are “column_#” even though they are displayed under the array as sequential integers. But this array of dictionaries seems to only be used for exposing the the data to the designer. When trying to write to the data in scripting it still is expecting an integer, making me think it is still seeing a list of lists, not the list of dictionaries the designer is using.
So I’ll leave 2 questions, and all of this is just for better understanding of how perspective is working with these tables behind the scenes:
Is there any situation where event.column will return a integer?
If someone needs to work with a list of lists in table and edit them, I’m thinking the only option would be to convert event.column from “column_N” to an integer “N-1” to then update the correct part of the data property?
While the property editor prevents users from supplying integers as object keys, you could always do so via a script:
data = [{0:'a', 1:'b'}, {0:'c', 1:'d'}]
self.getSibling("Table").props.data = data
This still doesn’t quite answer your question, however, because even though the keys are now integers, the generated event still returns the columns as a string: {"column":"0","row":0,"rowIndex":0,"value":"f"}
So I can’t think of any instance where an int would be returned as it seems we’re always casting the value as a string.