[Feedback] NEW Perspective Table

The new Perspective table component is here, and it’s loaded with tons of exciting features. These features include multiple headers and footers, expandable subviews, single and multi sort, frozen columns and rows, editability, selection, filtering, pagination, and much more.

We are opening this discussion for any feedback you may have regarding the table component, questions, and feature requests. We’d love to hear what you think, so let us know!

Below is an overview of the table component properties, it’s capabilities, and known issues we are currently working on, as it currently stands. This is planned to be removed once the user manual docs are updated.



​Data can consist of an array of arrays, a dataset, or an array of objects. It is preferable that the data is either a dataset or an array of objects since an array of arrays requires further processing. An individual data item can be either a string or number primitive or an object with reserved keys. If the data item is an object, it should at a minimum contain a value property. Other reserved keys include, ‘editable’, and ‘style’. These reserved keys make it possible to customize individual cells by specifying the cells edibility and individual style. For example:

city: {

  value: 'Folsom',

  editable: true,

  style: {

    backgroundColor: 'grey',

    classes: [] | ''



​When configured, specifies the selection possibilities of the table component. Similar to Vision module, you can select single, single interval, and multiple interval selection modes. The current selection and selection data is written back to the table components property tree so that the designer may use this information as they see fit. With the exception of the selection data property, the selection properties are bi-directional, meaning that if you were to change the value of the selected column property, it should be reflected in the table component.

Enable Filtering:

​When selected, enables the filtering component which is displayed above the table head. When filtering, the data in each row is checked to see if it might include the filter text. The preformed check is not case sensitive.

Enable Head:

When selected, enables the table head which includes the main table header along with the header groups.

Enable Foot:

When selected, enables the table foot which includes the main table footer along with the footer groups.

Header Groups:

Header groups are additional headers that are rendered above the main table header. Each header group equates to a single row which consists of individual cells containing title text. Individual cells of a header group can span multiple columns of the table (if available) by specifying the span property. Header group cells cannot span more than the available columns. The available columns to span are on a first come first serve basis. If the available columns to span is less than the configured span property, the cell will span the remaining space, assuming that there is at least one column to span.

Footer Groups:

See Header Groups.


Undeniably the most complex property of the table component in terms of configuration. This property represents an array of column configurations that may or may not correspond to the columns of the table. When empty, the table component will display all of the available columns. When non-empty, the table will display the same number of columns as there are column configs.


A string that matches this column config with a table column. This string must correspond to the default column name of the column.


Enables editing of all cells within this column. Note: can be overridden by the editable property configured on individual cells, so that the designer may enable editing on every cell of the column, expect for specific cells and vice versa.


Column rendering mode, a helper specifying what the column is expected to render.


Aligns the content of this column. Defaults to left.


Enables column resizing interaction.


Enables column sorting interaction.


View path used when render mode is set to view. Will render the view found at the view path within each cell of this column.


Used when render mode is boolean. Can specify how this boolean is represented in the UI, i.e. checkbox, toggle switch, value, etc.


Used when render mode is number. Can specify how this number is represented in the UI, i.e. progress bar, value, etc.

Progress Bar:

Progress bar configuration that is used when number is set to progress bar. Can specify the max value of the progress bar, as well as configure the bar and track colors, width, and shape.

Toggle Switch:

Toggle switch configuration used when boolean is set to toggle switch. Can specify selected and unselected color.

Number Format:

Number format string used when render mode is set to number.

Date Format:

Date format string used when render mode is set to date.


The width of this column. If resize is enabled, specifies the column width on initial load. Can be overridden during runtime only via resize handle interaction.


Column header configuration. Used to specify the header title, alignment, individual style, etc.


Same as header.


Applies style to this individual column. Useful for applying borders or background. Applying width has no effect on the width of the actual table column. This is merely used for applying underlying styles.


Rows configuration object which applies to all rows of the table component.


When enabled, each row will render an expandable subview which is toggled by the expandable arrow which is prepended to each row. The subview to render is specified by the view path property.


When enabled, applies odd and even background colors to each row of the table. Odd and even colors can be configured to the designer’s liking.


When enabled, applies a temporary background color to the current mouse-over’d row. The color can be configured to the designer’s liking.


Style which is applied to every table row.


Cells configuration object which applies to all cells of the table component.

Allow Edit On:

Configures edit initiation interaction of table cells.


Style which is applied to every cell.


Pager configuration object that enables table pagination. When rendering 1000+ rows with many enabled features, apply pagination can be used as an aid to maintain performance.


Enables top pager.


Enables bottom pager.


Select field options which specify how many rows to display.

Initial Option:

Initial option or number of rows to display on load. Should exist in the list of options.

Resize Mode:

Similar to vision, designers can specify whether the table resize mode is either fill or fixed. In fill resized mode, the total width of all the columns cannot be less than the width of the table. In fixed resized mode, the total width of all the columns can be less than the width of the table.


Column Resizing:

When configured through the designer via the corresponding column config, a column can be resized during runtime. The resize handle exists in a 36px swath centered on the end of the header cell. Hovering over this area will change the mouse cursor to column resizing. Dragging the resize handle will display a resize guide effectively providing a visual for the new column position as the user drags. These changes in width will not persist, and are merely for the convenience of the user.


When sorting is enabled on a column and the table head is enabled, a sort indicator will display to the right of the header cell content. The sort indicator will display the sort direction.

Single Sort:

Enabled by double clicking on a header cell.

Multi Sort:

Enabled by holding down ‘shift’ and double clicking on multiple header cells.


When selection is enabled, a user may select table data based upon the table’s selection configuration. In the browser, selection is indicated by a light blue overlay rendered on cells. The root selection, or most recently selected cell is distinguished from other selected cells by a light blue border. The root selection corresponds with the selected column and selected row props of the table component’s selection configuration.


Single mouse click enabled.

Single Interval:

‘Shift’ and single mouse click enabled.

Multiple Interval:

‘Command/ctrl’ + ‘shift’ and single mouse click enabled.


When editing is enabled on an individual cell, a user can edit a cell by performing the interaction specified by the ‘allow edit on’ property of the table component. When in edit mode, an editing cell with the corresponding cells content will be presented for edit. To commit this edit, the user must press the return or enter key. To exit the edit, the user may either press the escape key or select another table cell. When an edit is committed, the edited data is sent to the cell edit extension function of the table component (as of 11/25/18, extension functions are not implemented, so the data is just logged to the browser console.).


When paging is enabled, a user may use the provided buttons to navigate between available pages, change the number of rows displayed per page, and also jump to a specific page within range.


When filtering is enabled, a user may filter all of the data, not just the data being displayed when pagers are enabled, of the table component. If paging also happens to be enabled, the table will automatically page jump if it becomes necessary so that not to display an empty page (unless the first page).

Frozen Columns & Rows:


To freeze an individual column requires that the table head is enabled. A user may freeze an individual column by holding down ‘alt’ and double clicking the column header. This will fix the column within the bounds of the table so that the user may scroll to perform data comparisons. To unfreeze a column, hold down ‘alt’ and double click on the column header of the frozen column or of the source column. A frozen column can be dragged horizontally within the bounds of the table by selecting and dragging with the mouse. It is possible to freeze as many columns as a user may like. The user is not confined to freezing columns that are only visible when at scroll start position.


A user may freeze an individual row by holding down ‘alt’ and double clicking on the desired row within the table body. This will fix the table row within the bounds of the table. To unfreeze, perform the same operation on either the frozen row or the source row. A frozen row can be dragged vertically within the bounds of the table by selecting and dragging with the mouse. The user is not confined to freezing rows that are only visible when at scroll start position.

Known Significant Issues:

Table performance:

The table can become quite slow when you add around 1,000 rows. We are aware and are working on steps to virtualize the rows in the next phase of development. This is planned to begin shortly after this new table is released. A temporary work around is to use the tables pagers to limit the number rows that can be rendered at one time.

Property editor performance:

The property editor can become practically unresponsive when the length of the table data property gets close to 1,000 rows. This is unacceptable and is of high priority. We are working to mitigate this issue.


What properties can be/are passed to a nested view?

1 Like

If I recall correctly, the passed parameters use the column names as the keys, and the data for that column is the value.

A table with

|  id  |  quantity  |  myVar  |
|   0  |      7     |    abc  |

Would pass along parameters with the following structure

    'id': 0,
    'quantity': 17,
    'myVar': 'abc'
1 Like

I could see wanting the offset into the data and the apparent row offset as predefined keys… (-:

1 Like

That is definitely the parameters we expect to be passed to a view from a view cell. I realize that this is currently not the case for a view cell. Currently the entire row of data is being sent as parameters to the view from the view cell. This is on the list of items to fix, along with some others.

The current expected parameters are what you would expect for an expandable row which is configured as a view. When rows are configured to provide expandable subviews, the entire row of data will be passed as parameters back to the view.


Interesting idea. Do you mind providing a use case for this?


… thinking ahead to the message bus – having enough context for disconnected views to interact indirectly – in both directions.

Looks like this is going to be very useful in the future. But I was wondering, is there a way to stop it from highlighting the text when you click and drag? It’d be great to select as you click and drag, but without that its kind of odd when it just selects the actual text instead.

I agree. The browsers highlight selection (user-select) clashes with the way the table implements selection. We’ll take care of it. Thanks!



Okay, but by offset do you mean the row index and column index as it relates to the start of the available visible data in the table?

At the moment, the parameters passed back to the view from a view cell will have the shape:

   column: string | number;
   columnIndex: number;
   row: number; // This is the true row index, as it derived from the data source
   value: any;

I’m trying to customize a column like ‘translation list’ or ‘background list’ in vision module, but I can’t.

For example if I want to map the values of a column with some icons, how do it do?


Have you tried manipulating the data using a binding transform? It’s certainly not as convenient as configuring a translation list directly on a column, but it can be used to achieve the same effect, and much more.


Yes but I do not understand how to manipulate a single value or cell forall rows

Although not the prettiest solution, something like this might work. This operates on a bound dataset tag.

def transform(self, value, quality, timestamp):
	city_translations = {'Folsom': 'Folsom City'}
	transformed_value = []
	for row in range(value.getRowCount()):
		value_to_dict = {}
		for col in range(value.getColumnCount()):
			to_translate = value.getValueAt(row, col)
			if (value.getColumnName(col) == 'city' and to_translate in city_translations):
				value_to_dict[value.getColumnName(col)] = city_translations[to_translate]
				value_to_dict[value.getColumnName(col)] = to_translate
	return transformed_value

Hope this helps.



Here are notable features and fixes to the table component as of 12/13/18. These changes will apply in the next available build. Please let us know if you have any questions, or need clarification on any of these items.

  • Subview rendered by rows no longer appear highlighted on mouse over.

  • Views configured on a column now receive the following parameters:
    { column: string; row: number; value: any; columnIndex: number; rowIndex: number; }

  • Views configured on a row now receive the following parameters:
    { row: number; rowIndex: number; value: PlainObject; }

  • Toggle switches and checkboxes can now be horizontally aligned as configured.

  • Disable browser default text selection behavior across browsers.

  • Multiple interval selection no longer duplicates data.

  • Clear selection when both enableRowSelection and enableColumnSelection are disabled.

  • Selection data now includes data of columns added by additional column configs.

  • Table filter now shows a results count.

  • Pager page jump input field no longer requires double click to edit.

  • Boolean values and zero are now properly represented.

  • Added right click context menu to table body, currently dedicated to only copying selection data to clipboard.

  • Table no longer breaks with empty data source.

  • Display empty data source UI if data source is empty.

  • Render toggle switch/checkbox in edit cell if configured, instead of rendering the cell’s actual raw value.

  • Render either a text or number input field in edit cell depending on the cell’s raw value.

  • Add activePage prop to the pager prop to manage the current active page of the table if pagers are enabled.

  • Add advanced hide property to pager that results in the visual hiding of pagers.

  • Made default font size of the table body smaller.

  • Misc. UI updates.

1 Like

Selection data now includes data of columns added by additional column configs.

Do you have an example on how to use the data attribute under the selection?


Here are some of the latest features, updates and fixes to the table component.

  • Rows of the table component are now virtualized, meaning based upon the scroll position and height of the table, only the rows needed are rendered. This equates to being able to render thousands of rows in fractions of a second. Overall, a massive performance boost from the previous iteration. NOTE: There is a minor downside that comes from this virtualization. Columns that are set to render as view cells require that min row height be specified if the height of the configured view is greater than the default height of the rows. This is due to the fact that views have not completed their initialization lifecycle when pre-measuring row dimensions. This downside is a small price to pay for the performance gained from virtualization. Within the next few months, there will be an option to switch between virtualization and standard mode, so that you may choose which mode best suits your needs.

  • Cell editing is now full functional. There is a custom component event on the table called ‘onEditCellCommit’ which fires after changes are committed (‘Enter’ or ‘Return’ key press) to an editing cell. The event object has the shape: { column: string | number, row: number, value: any }. Please let us know what else you’d like to see included in the event object.

  • More intelligent column auto render modes. If the data happens to be a dataset, the render mode is derived from the dataset’s types.

  • New string render mode for column configs. Effectively just wraps the data in a string.

  • Various bug fixes including, applying specified formatting to valid dates, pager updating when the length of the data property changes, boolean auto render detection, and more.

1 Like

Is there going to be a way to access the filter value? I have two tables where I want to click one table to temporary filter the values in the second table. Outside of manipulating the dataset in the background I was looking to take some of the selected value data from table 1 to populate the filter in table 2. I’ve looked through available properties but don’t see a way to do that. Is this something that will be exposed in the property set for the table?

We can definitely look into exposing the filter property, but filtering the dataset using a binding + transform should also be an easy way to get it done.

1 Like

Is it possible for someone to provide an example of how to pass parameters to a subview?