Configuring Ignition Perspective Table Row Navigation

Karen Mitchell8 min read
HMI ProgrammingOther ManufacturerTutorial / How-to
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

The operator clicks a table row and the target page opens, but the displayed asset, record, or time range does not change. Navigation is working; parameter delivery or binding is not. Trace the click through four points: row data, generated URL, destination parameter container, and the binding that feeds the display or Named Query.

What is the screen telling you?

Separate a navigation failure from a data-context failure before changing the table. If the click does nothing, inspect the table event and its row-data extraction. If the destination opens with old or default data, inspect the URL and destination binding.

Operator symptom Likely boundary Check
No response to the click Table event Confirm that the row-click action fires and receives the clicked row.
Correct page, default values URL construction or destination binding Read the browser address and identify whether it uses path segments or a query string.
Correct record, wrong time range String-to-date conversion Inspect the incoming value before the eight-hour calculation.
First navigation works, later clicks retain old data URL update or parameter-change handling Repeat the test with two visibly different rows and record both resulting URLs.
Error appears after editing the URL manually Input validation or query execution Test type conversion and Named Query parameters without exposing internal error detail.

The first proof is simple: click one row and confirm that the browser reaches the intended page. Do not troubleshoot the query until that check passes.

Which table interaction should start navigation?

Use the table component's row-click event when the complete row should behave as the navigation target. Read data from the row delivered by that event instead of depending on a separate selected-row property whose update order may differ from the click event. This ties navigation to the row the operator actually clicked.

A link in the first cell is also valid. Use that configuration when navigation must be an explicit action or when other cells support editing, selection, or controls. Full-row navigation is faster for a read-only drill-down table, but it can conflict with selection or embedded cell actions.

Configuration Location Effect
Whole-row navigation Table row-click event Any suitable point in the row opens the detail page.
Link-cell navigation First element or link cell Only the visible link starts navigation, reducing accidental page changes.
Selection followed by a separate action Selected-row state plus button or event Adds an interaction step and requires explicit handling of selection timing.
  1. Capture the clicked row supplied by the table event.
  2. Copy the required record identifier and date value into local variables.
  3. Reject a row that lacks either required value rather than opening an incomplete destination.
  4. Build the destination using one parameter-delivery method.
  5. Call system.perspective.navigate with the completed URL.

Before connecting the destination query, temporarily inspect the two extracted values. Click two rows and verify that each event produces that row's identifier and date.

Which parameter model does the destination use?

Perspective supports two configurations in this case, and both work when the sender and receiver use the same model. Named route parameters populate the Primary View's parameters. Query-string parameters populate the page's urlParams object. A query string does not populate view.params merely because the keys have matching names.

Method Page or route configuration Example URL Read at destination
Named route parameters /devzl7/:which/:when devzl7/6/1666263540000 Primary View parameters such as view.params.which and view.params.when
Query-string parameters Normal page route /devz17?which=6&when=1666263540000 self.page.props.urlParams.which and self.page.props.urlParams.when

The route spellings devzl7 and devz17 differ by a letter in the installation notes. Use the exact route configured for the destination page; the browser path must match it character for character.

Choose named route parameters when the identifier and timestamp define the page's primary context and existing bindings already target view.params. Choose query-string parameters when the values are optional page state or when bindings are intentionally based on page.props.urlParams. For the described view, named route parameters require fewer binding changes because the label and query already reference view parameters.

The check at this stage is container-specific: path values must appear in the Primary View parameters, while query-string values must appear under the page's urlParams.

How do named route parameters connect to the Primary View?

Configure the page route with ordered placeholders: /devzl7/:which/:when. The segment after devzl7 maps to which, and the next segment maps to when. Order is part of the contract.

  1. Declare :which and :when in the destination route.
  2. Create matching parameters on the Primary View used by that page.
  3. Extract the clicked row's identifier and date representation.
  4. Construct a path in the same order, such as devzl7/6/1666263540000.
  5. Navigate to that path.
  6. Bind the destination label and Named Query inputs to the Primary View parameters.

Do not append ?which=... and expect this configuration to fill view.params. The colon placeholders consume slash-delimited path segments, not query-string keys.

Test with identifier 6 and timestamp text 1666263540000. The destination should receive "6" and "1666263540000", in that order. If those strings appear in the Primary View parameters, the route-to-view connection is proven.

How do query-string parameters connect to the page?

Query parameters follow a question mark and use ampersands as separators. The general form is /devz17?which=test&when=date. With row values inserted, it becomes /devz17?which=6&when=1666263540000.

An absolute navigation target can follow this form:

system.perspective.navigate(url='http://<GatewayIP>:<port>/data/perspective/client/<projectName>/view?key=8')

Replace the gateway, port, project, route, keys, and values at runtime. Encode values before inserting them when they can contain spaces, ampersands, question marks, slashes, or other reserved URL characters. Raw concatenation can turn one value into multiple parameters or alter the route.

  1. Leave the destination page on its normal route; colon placeholders are not required for this method.
  2. Build the query string with ? before the first parameter and & before each additional parameter.
  3. Navigate to the completed URL.
  4. Read the values from self.page.props.urlParams.which and self.page.props.urlParams.when.
  5. Bind or transform those page properties into the inputs used by the view.

If the address bar shows both keys but view.params stays unchanged, that is the expected result of reading the wrong container. Confirm the same values under page.props.urlParams before proceeding.

How should the timestamp and identifier be converted?

Every URL parameter arrives as a string, regardless of whether it traveled through a named path segment or a query string. The values "6" and "1666263540000" are therefore text at the destination.

1666263540000 has the form of an epoch timestamp in milliseconds. Unix time is measured from the Unix epoch at 1970-01-01 00:00:00 UTC, not a date in 1969. Convert the string to an integer-compatible numeric value and then construct the date value expected by the destination binding or query. Apply the eight-hour subtraction only after conversion to a date or timestamp type. A subtraction performed on the original string is a type error, not time arithmetic.

Incoming key Incoming type Conversion Use
which String Convert to the exact identifier type expected by the Named Query, or retain text if the query parameter is textual. Record selection
when String Validate numeric syntax, convert milliseconds to a date value, then perform date arithmetic. Displayed time and shift-range calculation

Treat URL values as untrusted input. A Named Query improves separation between data and SQL only when values enter declared parameters rather than being concatenated into SQL text. The Named Query being of type Query does not make arbitrary URL content safe by itself. Validate the identifier's type, reject malformed timestamps, constrain acceptable ranges, and avoid displaying detailed internal errors to the client. An edited value such as where should fail validation before query execution.

The proof is a paired display: show the converted destination timestamp and its calculated eight-hour-prior value, then compare both with known expected times for the clicked row.

How is the complete row-to-query path verified?

  1. Select two table rows with different identifiers and timestamps.
  2. Click the first row and confirm that the URL contains its two values in the chosen path or query-string format.
  3. Inspect the correct destination container: Primary View parameters for /devzl7/:which/:when, or page.props.urlParams for ?which=...&when=....
  4. Confirm that both incoming values are strings before conversion.
  5. Verify that which converts to the Named Query's declared input type.
  6. Verify that when converts to a date and that the eight-hour-prior calculation uses the converted date.
  7. Confirm that the label displays the clicked row's time and the Named Query returns data for the same identifier and range.
  8. Navigate from the first row to the second without reloading the session. Confirm that the URL, parameter container, label, and query result all change together.
  9. Edit each URL value with malformed text and confirm that validation blocks the query without returning component names, query details, or diagnostic internals to the client.

For a system running Ignition 8.1.19, first eliminate route, container, and conversion mismatches before investigating a subsequent-URL-update defect. A reproducible update test needs the initial URL, second URL, page route, chosen parameter method, and observed values at the destination container.

The final commissioning check is a second-row click: the address changes, the correct parameter container changes, the converted timestamp and eight-hour range change, and the Named Query returns the second row's data.

FAQ

What happens if I use ?which=6 but read view.params.which?

The page opens, but view.params.which does not receive the query-string value. Read self.page.props.urlParams.which, or change the route to a named path such as /devzl7/:which/:when.

What happens if I pass 1666263540000 through the URL?

It arrives as the string "1666263540000". Validate it, convert it from epoch milliseconds to the required date type, and only then calculate the time eight hours earlier.

What happens if a user puts where or SQL text in the URL?

Reject it through identifier and timestamp validation before running the Named Query. Pass accepted values through declared query parameters and keep internal component and query details out of client-visible errors.

What happens if the first row works but the second row shows old data?

Compare both generated URLs and inspect the selected destination container after each click. The final verification passes only when the second URL, destination strings, converted date range, label, and Named Query result all change to the second row.

Back to blog