Configuring Perspective Table Column Widths in Ignition

James Nishida8 min read
HMI / SCADAOther ManufacturerTroubleshooting
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

Fault Signature and Cause Map

The setup: an Ignition Perspective Table whose props.data is written by a script as a dataset with three columns, MaterialName (String), Setpoint (Double), and Actual (Double). Three column objects were added under props.columns so the name column could be wider than the two numeric columns. Editing columns.0.width changed nothing. A fourth, blank column added by hand could not be resized either. Toggling strictWidth on and off made no difference.

The exported column config showed two defects at once. Every column object had field set to "", and every width was a string with a unit: "100px" on column 0 and "5px" on columns 1 and 2, all with strictWidth: true. Because the two defects stack, fixing either one alone produces no visible change. That is why each individual fix appeared to fail. Width started working only after both were corrected.

Symptom Reading to take Cause Go to
Width edits ignored on every column, including a manually added blank one field is empty in props.columns Column config is not attached to any dataset column Check 2
field filled in, but the column shows no data or ignores settings Compare field to the dataset header character by character Case or spelling mismatch. field is case-sensitive. Check 1
field correct, but width still ignored with strictWidth: true width contains "px" or is quoted String supplied where a number is expected Check 3
Widths change, but not to the sizes you typed strictWidth: false Widths are being treated as proportional weights Check 4
Width differs between clients, or differs after a drag resizable: true A runtime user override is masking the configured initial width Check 5

Check 1: Dataset Header Names

Before anything else, confirm the exact column names the table is actually receiving. A script that builds the dataset sets those headers, and the names you expect may not be the names that arrived.

  1. In the Designer, select the Table and open the dataset editor button to the right of props.data.
  2. Record each header exactly, including capitalization. In this table they are MaterialName, Setpoint, and Actual.
  3. Compare them to the header list in the script that writes props.data. Look for trailing spaces, underscores, or case changes introduced by the script.

Outcome A: the headers match what you intend to reference. Go to Check 2.
Outcome B: the headers differ. Either correct the script or use the headers as they actually appear. Do not move on until you have the literal strings written down, because Check 2 depends on them.

Check 2: field Mapping in props.columns

When props.columns is empty, the Table generates columns from the data keys on its own. Once you add column objects, each object applies to data only through its field property. With field set to "", the object has no data column to act on, so width, justify, render mode, and every other setting on it do nothing useful. This also explains the blank fourth column: with no field, it was never a real column to size. The match against the dataset header is case-sensitive. materialname does not bind to MaterialName.

Isolate the mapping with one column before rebuilding all of them:

  1. Remove every object from props.columns.
  2. Add one new object.
  3. Set its field to one header copied from the dataset editor, for example MaterialName, with matching case.
  4. Confirm the table now renders that column's values from the dataset.

Outcome A: the column renders data. The mapping is good. Go to Check 3.
Outcome B: the column is blank or shows no values. The field string does not match the header. Return to Check 1.

Check 3: width Data Type Under strictWidth

This defect keeps width from working even after the fields are correct. With strictWidth: true, the Table expects width to be a number. The Perspective Table section of the Ignition User Manual, in the columns property descriptions, states that the value is numeric. Setting "100px" passes a string containing a CSS unit, and the table does not apply it as a fixed width.

Entry in width Type Result with strictWidth: true
"100px" String Not applied. Column stays at default sizing.
"100" (quoted) String Same risk. Enter it as a number, not text.
100 Number Applied as the column width
  1. Open props.columns[0].width in the property editor.
  2. Delete the px suffix and enter a bare number. Confirm the property editor shows it as a numeric value, not a quoted string.
  3. Repeat for every column object.
  4. If a script writes props.columns, have it assign numbers, for example width = 250 and not width = "250px". Otherwise the script will overwrite the fix on the next onStartup.

Outcome A: column 0 visibly resizes. The fault is cleared. Go to Check 4 to pick the sizing mode.
Outcome B: no change. Re-verify the field strings (Check 2), then check whether a binding or script is rewriting props.columns at runtime.

Check 4: Fixed Versus Proportional Width

strictWidth changes what the width number means. Toggling it on the original config showed no difference only because the field and type defects were still present. Once those are fixed, the two modes behave differently:

strictWidth Meaning of width Use when
true Column width value, numeric A column must hold a known size regardless of table width
false Relative weight compared with the other columns Columns should scale with the container, for example in a flex layout using grow: 1

In proportional mode, each column's share of the table width is its weight divided by the sum of all weights:

share_i = width_i / (width_1 + width_2 + ... + width_n)

Manual example: 10, 15, 25  -> sum 50
  10/50 = 20%   15/50 = 30%   25/50 = 50%

Applied to this table (derived values):

Weights (MaterialName / Setpoint / Actual) Sum Resulting shares
50 / 25 / 25 100 50% / 25% / 25%
2 / 1 / 1 4 50% / 25% / 25% (same ratio, smaller numbers)
100 / 5 / 5 (original numbers, px removed) 110 about 90.9% / 4.5% / 4.5%

The last row is a pitfall. If you strip px from the original values without rethinking them, the numeric columns collapse. Under strictWidth: true, a width of 5 makes the Setpoint and Actual columns unreadably narrow. Under false, they get under 5% each. Choose the weights for the layout you want, not the leftover numbers.

Proceed with strictWidth: false if the table sits in a flex container (this one has position.grow: 1 and basis: "400px") and should scale with the page. Use true when the name column must hold a fixed size.

Check 5: resizable and Runtime Overrides

When resizable is enabled on a column, width sets the width at initial load, and an operator can drag it to a different size in the running session. A dragged width in an open client masks whatever you just changed in the Designer. In this config, column 0 had resizable: false and columns 1 and 2 had resizable: true.

  1. Decide per column whether operators may drag it. A fixed name column with resizable numeric columns is a valid mix.
  2. When testing width changes, open a fresh session or reload the view, and do not drag any headers before you read the widths.
  3. If one client still shows a different width than the others, treat it as a user override, not a configuration fault.

Corrected Column Configuration

This is the resolving branch: field matched to the headers and width entered as numbers. Apply it in this order:

  1. Clear props.columns.
  2. Add three objects. Set field to MaterialName, Setpoint, and Actual, copied from the dataset editor.
  3. Set strictWidth on each object according to Check 4.
  4. Enter width as bare numbers.
  5. Set resizable per Check 5.
  6. Leave all other column properties (render, justify, filter, numberFormat) at their existing values. They do not affect sizing.

Proportional layout, name column at half the table width. Only the sizing-related keys are shown, and the weights are example values:

"columns": [
  { "field": "MaterialName", "width": 2, "strictWidth": false, "resizable": false },
  { "field": "Setpoint",     "width": 1, "strictWidth": false, "resizable": true  },
  { "field": "Actual",       "width": 1, "strictWidth": false, "resizable": true  }
]

For a fixed name column instead, set strictWidth: true on the MaterialName object and give it a numeric width sized to your longest material name. Size the numeric columns large enough to show the 0,0.## formatted values and their header titles.

The dataset script and the column config are independent. The onStartup script can keep rewriting props.data freely, as long as the header names it produces stay identical to the field strings. If the script changes a header, the matching column object stops applying.

Verification

  1. In the dataset editor, confirm the headers still read MaterialName, Setpoint, and Actual after the onStartup script runs, not only in the Designer's static data.
  2. In props.columns, confirm each field matches one header exactly, and that every width shows as a number with no px and no quotes.
  3. In the Designer preview, change props.columns[0].width by a large step, for example doubling it. Confirm column 0 visibly changes, then set it back to your target.
  4. For proportional mode, resize the browser or container and confirm the columns keep their ratio. At weights 2/1/1, the name column should stay at about half the table width.
  5. Open a new client session and, without dragging any header, confirm all three columns load at the configured sizes. Confirm the pager page (15 rows per page) renders the same widths across pages.

FAQ

Does strictWidth accept pixel strings like "100px" on a Perspective Table column?

No. With strictWidth: true, the Table expects width as a number, so "100px" is not applied. Enter 100 with no unit and no quotes.

Can I leave field blank and size columns by their index in props.columns?

No. A column object with field: "" is not attached to any dataset column, so its width has nothing to act on. Set field to the exact dataset header, such as MaterialName.

Does the Perspective Table field property ignore case when matching dataset columns?

No, the match is case-sensitive. materialname will not bind to MaterialName. Copy the header from the dataset editor next to props.data.

Can I make one column take a fixed share of the table width?

Yes. Set strictWidth: false on all columns and use relative weights, where each column's share is its weight divided by the total. For example, 10/15/25 gives 20%/30%/50%, and 2/1/1 gives the name column 50%.

Back to blog