Perspective Table Editing: Use Embedded Views, Not Blur

Claire Rousseau8 min read
HMI ProgrammingOther ManufacturerTechnical Reference
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

Before anything else, confirm whether the operator must preserve a typed value when moving directly from one row to the next. The standard Perspective table edit cycle treats Enter as the commit action. Clicking another cell can end the edit without exposing the typed value through onEditCellCancel; that event reports the original table value. For rapid multirow entry, render an input view in the target column and write each committed value back to props.data.

Editing-path selection

  1. Reproduce the exact operator sequence. Edit one cell, type a distinct test value, and click the same column in the next row without pressing Enter. Read both the event payload and props.data. If the new value appears in the data, keep the standard editor and verify downstream persistence. If the event supplies the original value, continue to the next check.
  2. Classify the column data type. For a Boolean that only needs toggling, evaluate a filtered table click handler. For text, numbers, or inputs requiring controlled commit behavior, use an embedded view.
  3. Identify the write target. Pass a stable rowId, the permitted columnId, and the entered value from the embedded view. Do not move on until the parent can resolve one unique table cell.
  4. Select the commit trigger. Decide whether the value writes on input change, focus departure, or another deliberate action. Use deferUpdates when the input must hold intermediate keystrokes before publishing a completed value.
  5. Verify repeated entry. Change several consecutive rows by clicking directly from one embedded input to the next. Confirm every intended cell changes once and unrelated columns remain untouched.

Cancel-event value check

Read event.value during onEditCellCancel while reproducing the click-away sequence. The decisive branch is the value carried by that event:

Observed result Meaning Next check
event.value contains the original cell value The standard editor discarded or withheld its transient input when the edit was canceled. The cancel event cannot serve as a commit event. Choose the data-type path.
event.value contains the typed value The active configuration exposes the pending input at cancellation. Validate the value, write it to the intended cell, and test keyboard and pointer navigation.
props.data changes only after Enter Enter is the commit boundary for the current editing path. Keep Enter as an operator requirement or replace the cell editor with an embedded input.

A cancel notification describes termination of an editing transaction; it is not a reliable substitute for a value-change or commit notification. Once the test shows the original value in event.value, stop adding scripts around that event. The typed characters exist only in the editor's transient state, and the cancel payload does not provide a supported route to recover them.

Data-type branch

For a Boolean column, a table-level click handler can bypass the standard editor and invert the value directly. Read the clicked row and column, confirm that the column is the designated Boolean column, and only then toggle the cell. The controlling logic is:

# Pseudocode: execute only for the permitted Boolean column
if selectedColumn == booleanColumn:
    props.data[selectedRow][selectedColumn] = not props.data[selectedRow][selectedColumn]

The column filter is mandatory. Applying not to every selected cell produces undefined or unintended results for text, numeric, and other non-Boolean data. After the write, confirm that one click changes the checkbox once and that clicking any other column leaves its value unchanged.

A Boolean rendered as a normal editable checkbox may require one click to select the cell and another to toggle it. If that interaction remains acceptable, retain the standard editor. If the operator expects a direct one-click toggle, use the filtered click-handler path or render a dedicated checkbox view.

For text or other values that require typing, branch to an embedded view. A text-entry view exposes input behavior unavailable through the basic table cell edit cycle, including controlled update deferral. Confirm that the embedded control can receive the current value and return the completed value before connecting it to production data.

Cell identity and write path

Configure the target column to render a simple view containing the input control. Pass enough context into each view instance to locate its cell: rowId, columnId, and the current value. The embedded view sends those identifiers and the new value to a message handler, which updates the corresponding element of props.data.

Field Purpose Acceptance check
rowId Locates the record being edited. Sorting or moving focus does not redirect the write to another record.
columnId Restricts the write to the intended field. Unsupported columns are rejected or ignored.
Current value Initializes the embedded input. The displayed value matches the table model before editing.
Entered value Supplies the candidate replacement. The handler receives the completed value, not the prior value.

The write operation can be expressed as the following data-flow pseudocode:

props.data[rowId][columnId] = enteredValue

Treat that expression as the target relationship, not as a complete production handler. The handler must first confirm that columnId belongs to the editable set and that rowId resolves to the intended record. If the table uses a transformed or externally bound dataset, route the accepted edit to the authoritative data destination as well; otherwise, a refresh can replace the displayed edit with the source value.

Commit-trigger decision

Read when the embedded control publishes its value, then select the branch that matches the operator workflow:

Trigger Behavior Primary risk Verification
Each value change Writes while the operator edits. Partial text or intermediate numeric input may be published. Type a multi-character value and count the accepted writes.
Focus departure Writes when the operator clicks the next row. A mouse-leave trigger can fire merely because the pointer crossed the control, even when editing was not complete. Move the pointer without editing, then edit and click the next input.
Deferred update Holds intermediate input until the configured publication point. An unhandled navigation path can leave a pending value uncommitted. Test pointer navigation, Enter, and departure from the table.

deferUpdates is useful when the operator must type a complete value before the table receives it. Pair it with a clear commit path that fires when focus moves to the next embedded input. Do not use mouse leave as the only trigger unless testing proves that ordinary pointer movement cannot cause unwanted writes.

Whatever trigger is selected, send the row and column identity with the value in the same message. Reading the table's current selection later creates a race: focus may already have moved to the next row by the time the parent handles the update.

Embedded-view implementation

  1. Create the cell view. Add the required text-entry or checkbox control and define inputs for rowId, columnId, and the current cell value. Confirm that separate rows display their own values.
  2. Render the view in the editable column. Set that column's renderer to the view and supply its viewPath. Confirm that the control appears in every intended row and nowhere else.
  3. Configure input publication. For multi-character entry, apply deferUpdates when intermediate keystrokes must not update the table. Confirm the chosen commit action emits the final value.
  4. Send the edit message. Include rowId, columnId, and the entered value. Confirm the handler receives all three from each row instance.
  5. Validate the target. Accept only the configured editable column and resolve the row identity before writing. Confirm a fabricated or unsupported column identifier produces no change.
  6. Update the table model. Write the new value to the matching location in props.data, then route it to the application's authoritative storage if persistence is required. Confirm the visible cell and underlying source agree.
  7. Repeat across rows. Type a value, click directly into the same column on the next row, and continue through several rows. Do not move on until every departure commits the completed value without an Enter keystroke.

Failure isolation and verification

Symptom Likely cause Corrective check
Clicking the next row restores the old value The standard cell editor canceled, or the embedded input never published its deferred value. Trace the input's commit event and verify the message contains the final value.
The next row receives the previous row's value The handler used current selection instead of the identity sent by the editing view. Log and compare rowId at edit time and write time.
Unrelated cells change The script did not filter columnId or selectedColumn. Restrict writes to the declared editable column.
A checkbox takes multiple clicks The first click selects the cell and the next activates the standard editor. Use a filtered table click handler or an embedded checkbox view.
An edit disappears after refresh Only the displayed props.data value changed while the authoritative source remained unchanged. Verify the accepted value at the source used to repopulate the table.
Partial values are stored The input publishes on every change. Apply deferred publication and retest with multi-character input.

Run the acceptance test with at least three consecutive rows and distinct values. Test clicking forward, clicking backward, pressing Enter, leaving the table, and clicking a noneditable column. Read both the visible cells and the authoritative data destination after each path. A passing implementation commits each completed edit once, preserves row identity, rejects writes to other columns, and retains the values after the table reloads.

FAQ

What happens if I use onEditCellCancel to save the typed value?

If onEditCellCancel reports the original value in event.value, the transient typed value is unavailable through that event. Use an embedded input with its own commit action instead.

What happens if I toggle a Boolean from every table click?

Cells outside the Boolean column can receive an invalid or unintended not operation. Filter selectedColumn before changing props.data.

What happens if deferUpdates is enabled but focus moves to another row?

The completed value must publish through the configured commit path when focus departs. Test that exact transition; if no message arrives, add the appropriate focus-departure commit behavior to the embedded input.

How do I verify Perspective Table edits survive a reload?

Edit several rows without pressing Enter, confirm the corresponding rowId and columnId values at the authoritative destination, then reload the table. The final check passes only when every edited row returns with its new value.

Back to blog