Perspective table delete row

I have a table in Perspective that the client would like to be able to delete entries from. Initially I accomplished this through an onCellEdited script by getting the dataset, deleting the row, and setting the table data equal to the modified dataset, and it worked well. The client has now requested to be able to delete entries with a button, so I used a very similar script, but every time I try to delete the lowest row in the set, it errors the component. I’m not really sure of what the problem may be, as a near identical script worked in the onCellEdited script. Is there something I’m missing here?


In looking at the documentation for dataset.deleteRow, you’re passing an argument of an unexpected type. You’re supplying an object which defines the values of the row, whereas the function deleteRow expects an int index of the row to delete. You’ll need to loop through the dataset to determine which row is selected from the data you have in row.

Hi @cmallonee,

the same delete function i tried to use on button on click event. I am doing 2 events on button click 1) open popup 2) delete the selected row.
I am able to open popup and delete the table but after 10-20sec the deleted row value gets back in table. I am polling off also but dont know why is it happening also i am using Oracle database for query data. My application is to delete the row from view table but now from database.

Please supply your code for the deletion.

I am attaching onclick event code and query binding. The database used is oracle and the date variable used in named query will take data from last 7 days.


You’re deleting the row from the dataset, but that is not the same as deleting it from the database. Your query only selects the data, and since you haven’t removed the row from the database, when the query gets run again, the row “reappears” in the table.

Ignition Dataset is not equal to database table.

When you remove the row from the dataset in your script you need to also remove the row from the database, either through a system.db.runPrepUpdate or a system.db.runNamedQuery.

Hi,
I dont want to delete the data from database but only from view table data as the operator need to know that the data he has deleted is sent to MES thats why i am doing the delete function. do you have any other solution to notify operator that data is sent or is already being sent

Then don’t use a query binding to populate the table. Its whole purpose is to display data from the database. You will need to script a suitable state machine that initializes an intermediate property once from the database, then all further manipulations work with that property.

So, i need to use named query in session custom property and then use it anywhere but i have date used to filter so will it update the dummy data or i need to do it separately

This is how I would do it.

def runAction(self, event):
    tbl_assets = self.getSibling("Tbl_Assets")
    data = tbl_assets.props.data
    selected_row = tbl_assets.props.selection.selectedRow

    # Check if a row is selected
    if selected_row is not None:
        # Get the column names from the first row (assuming all rows have the same structure)
        columns = list(data[0].keys())
        
        # Extract the rows as a list of lists (instead of a list of dictionaries)
        rows = [[row[col] for col in columns] for row in data]

        # Create the dataset from the columns and rows
        dataset = system.dataset.toDataSet(columns, rows)

        # Delete the selected row from the Dataset
        dataset = system.dataset.deleteRow(dataset, selected_row)

        # Convert the updated Dataset back to a list of dictionaries
        pyDataSet = system.dataset.toPyDataSet(dataset)
        
        # Ensure correct conversion by explicitly creating dictionaries from the dataset
        data_list = [{columns[i]: row[i] for i in range(len(columns))} for row in pyDataSet]
        
        # Update the table data with the new list (row removed)
        tbl_assets.props.data = data_list
        
        # Reset the selected row
        tbl_assets.props.selection.selectedRow = None
    else:
        # Handle case when no row is selected (optional)
        system.perspective.print("No row selected for deletion")

use this instead

rows = [row.values() for row in data]

edit: wait, you're converting the whole thing to a dataset just to delete a row, then converting back to a list of dicts ?

Just put this in a "delete_selected_row" script on the table:

def runAction(self, event):
	if self.props.selection.selectedRow is not None:
		self.props.data.pop(self.props.selection.selectedRow)

Then call this script from whatever button or event:

def runAction(self, event):
	self.getSibling("Tbl_Assets").delete_selected_row()

Though I'd probably open a confirmation popup on click, then send a delete_row message back to the table.

1 Like

opening a confirmation popup is already giving me a hard time :smile:

Here's an example project with a table and 2 buttons to remove the selected row from that table, one with a confirm popup and one without.
delete_row.zip (53.6 KB)

I changed the delete function a bit to handle both datasets and lists of dicts.
The confirmation popup is my standard one, the same one I sent you before, so it has a few parameters that aren't used here but I wasn't gonna make a new one just for this.

1 Like