Perspective table editing help

Is there an example available on how to catch and process a committed edit in a Perspective Table? Thanks in advance…

Pretty simple, you just bind onEditCellCommit. You’ll get an event dictionary that has row, column, and value entries that you’ll need to set, like so:

self.props.data[event['row']][event['column']]['value'] = event['value']

or just (to remove editability and styles)

self.props.data[event['row']][event['column']] = event['value']

or

self.props.data = system.dataset.setValue(self.props.data,event['row'],event['column'],event['value'])

If you don’t explicitly set the value during the function, that’s equivalent to canceling the edit. That way you can do you error checking and only commit it at the very end.

What makes it painful is that self.props.data can be a dataset, an array of arrays, or an array of objects that itself contains either values, arrays, or objects with extended properties. It’s a matter of testing for each or handling exceptions, then.

1 Like

Here’s what I’m doing when data is a dictionary.

	# this makes the presumption data is a list of dictionaries where row is the element number...
	logger = system.util.getLogger("TEST")
	
	colName = event["column"]
	row = event["row"]
	id = self.props.data[row]["id"].value
	self.getSibling("Label").props.text = str(row) 
	update = "UPDATE users SET " + colName + "=? WHERE id = ? "
	p = [event["value"],id]
	r = system.db.runPrepUpdate(update,p)
	logger.info(str(type(self.props.data)))
	if r != 0:
		self.props.data[row][colName].value = event["value"]
2 Likes

All are good and valid examples to help solve catching and processing a committed edit from the table component. Going to go ahead and mark this as resolved. -Yousuf

I need help just getting to the edits.
I have a Perspective table with an indirect binding to dataset tags.
I’m impressed with how simple it was to configure and how fast it responds.

I can’t figure out how to make the cells editable.
I’ve messed with all the cells, rows and columns properties I can think of but haven’t found the right one yet.

While I’m at it, how can I make the columns resizable like the Vision PowerTable?

Thanks, Lynn

Add a set of props.columns corresponding to the number of columns you want to show. In each one, set the field property to the column name, then you can make editable true, resizable true, etc. if you need to programmatically create a dynamic number of columns, you can right click-copy the entire column to get the JSON, then use:

import json
json.reads

columnJSON = '<json goes here>'
columnSet = []
for i in range(columnCount):
    columnSet.append(json.reads(columnJSON % (<if you want to use basic string transformations>)))
    columnSet[i]['field'] = 'Column Name'

myTable.props.columns = columnSet

Note that any columns you choose not to display also won’t show up in props.selection.data[0], in case you want hidden columns with extra information for any reason. A workaround is to give them a width of 0 or 1.

2 Likes

No problem showing the data - the table is populated instantly from the dataset tags when the indirect value changes but it is read-only. I want to use the table as an input source for the user to edit the data, insert rows, delete rows, etc.
The property for cells allowEditOn:single-click doesn’t allow the cells to be edited (neither does double-click or long-press).

I just realized the table is a “Display” component, I’m trying to use it as a “Display + Input” component like the Vision PowerTable.

Did you create the columns fields and set editable:true on them? It works, I promise you. It’ll either immediately edit the underlying dataset or object, or you can put a hook on onEditCellCommit to decide what to do with the edit (like propagate it to the database).

I think the new 8.0.2 nightly does let you use allowEditOn in a single cell without having to define editable on either the underlying object or the column definition, though.

1 Like

Thanks for this dynamic json column add code. I knew you could copy the json but I wasn’t sure how that integrated with other stuff. I figured it was easy.

Thank you @silverbacknet!
With all of the columns and data displayed, I wasn’t in the mind-set to create a column that was already displayed and populated with data. Now they are editable, have built-in column sort and are resizable.

So maybe i’m missing something, but I’ve taken the table component and dumped it on a perspective view with no attached data binding, just using the dataset that comes with it. I add a column, put in the field name, make it editable which allows editing of the cell, but when I hit enter the change isn’t committed to the dataset. Am I missing a step somewhere or is this possibly a bug?

Just like the power table in Vision, you need to implement an extension function to actually send your change into the table’s underlying data - see the onEditCellCommit component event.

1 Like

I had a similar problem as OP did. I’ve used your code to dynamically fill the columns prop, but I’m running into a strange issue. even though I make sure my list/array filled with my modified JSON objects contain the correct values, it populates the columns prop with however many of the exact same JSON object, effectively only showing one of my columns, always the last.
Here is my code in case you spot something obvious:

	import json
	
	#clear the columns prop
	self.getSibling("Table").props.columns = []
	#get the table name from the custom prop on the root
	tableName = self.parent.custom.tableName
	#construct and fire a query to return the columns in the table.
	queryGetColumns = "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = N'"+tableName+"'"
	columnNames = system.db.runPrepQuery(queryGetColumns)
	#construct and fire a query to return the column with identity
	queryGetUnique ="SELECT name FROM sys.identity_columns WHERE OBJECT_NAME(object_id) = ?;"
	argList = [tableName]
	uniqueColumn = system.db.runScalarPrepQuery(queryGetUnique, argList)
	print 'unique = '+uniqueColumn
	#make an array/list to fill with JSON objects
	propsColumns = []
	#load in the JSON format for columns prop
	columnJSON = json.loads(self.getSibling("Table").custom.columnFormat)
	#counter
	i = 0
	#for every column fill propsColumns with a JSON object
	for row in columnNames:
		for column in row:
			propsColumns.append(columnJSON)
			propsColumns[i]['field'] = column
			#if the column ins't the identity column make it editable
			if column != uniqueColumn:
				propsColumns[i]['editable'] = bool(1)
			else:
				propsColumns[i]['editable'] = bool(0)
			print propsColumns[i]['field']
			print propsColumns[i]['editable']
			#counter + 1
			i = i+1
	#populate columns prop
	self.getSibling("Table").props.columns = propsColumns

Do you have any idea what might be causing this or is this simply a bug?

You created a reference to the json object and edit the same object all the time.
Instead of edit the reference you have to create a copy of the json object for each instance.
you can do it like this: jsoncopy = dict(columnJSON)