Table Views

At the heart of a Table View is a list of columns which is defined in the view columns property.

Note

First make sure you've read the basics about views before continuing on this page. It will make it easier for you to understand table views.

Defining Columns Globally

Views have access to globally defined columns, which are defined in state.globalEntities.availableColumns. This is covered in detail in the intro page about views - so make sure you've read that first.

defaultState = {
  globalEntities: {
    availableColumns: {
      id: { field: 'id', dataType: 'number' },
      name: { field: 'name', label: 'Name', dataType: 'text' },
      language: { field: 'language', dataType: 'text' },
      license: { field: 'license', dataType: 'text' },
      stars: {
        field: 'github_stars',
        editable: true,
        dataType: 'number',
      },
      '2xstars': { expression: '[stars] * 2', dataType: 'number' },
      '10xstars': {
        valueGetter: ({ data }) => data.github_stars * 10,
        dataType: 'number',
      },
    },
  },
};

Note

The keys in this object are the id of the respective column and the value is the column definition.

Using column references in view.columns

After the columns have been declared in state.globalEntities.availableColumns, they can be referenced in views.

Referencing columns in views
defaultState = {
  view: {
    currentViewId: 'myView',
    views: [
      {
        id: 'myView',
        label: 'My View',
        columns: [
          { id: 'name' },
          { id: 'language' },
          { id: 'license' },
          { id: 'id', visible: false },
          { id: 'stars', editable: false },
        ],
      },
    ],
  },
};

The only mandatory property in a column reference inside a view is the id - which points back to the respective column in state.globalEntities.availableColumns.

When referencing a column, you can override all of the non-mandatory properties from the column definition.

The view.columns property is an array and defines which columns (and their order) are currently present in the view (though some can be configured as visible: false).

Note

A view can be configured with any of the columns available in globalEntities.availableColumns.

When referencing a column in a view, you can override most of the column properties specified in the column definition. If you choose to only reference the column by the id, it will use the default configuration that is defined in the column definition as specified in the global entities

Note

If the view.columns array references a column id that's not defined or available to the view it is simply ignored and not rendered.

There is an exception to this rule, which is for row group columns.

The id of the group column doesn't need to reference an existing column definition - but make sure it's still unique in the view.

Besides that, a group column is defined like any other column in the view, but it has the groupBy property configured.

The column groupBy can be either a string or a string[] (the value(s) in the groupBy needs to reference an existing column in the state.globalEntities.availableColumns ).

  • if the groupBy is a string, the group column will render the grouping values for that column (you can have more than one group column with groupBy set to a string).
  • if the groupBy is a string[], the group column will render the grouping values for all the specified columns (you can only have one group column with groupBy set to a string[]).

Defining Row Groups

Group columns behave very much like any other normal column in a table view. This makes it very easy to configure group columns like you already do with normal columns.

Note

The single most imporant difference with group columns is that the id of a group column will not reference an existing column.

Also, group columns will define a groupBy property which tells them how to perform grouping.

Apart from these two properties, everything else is the same.

This makes it very easy to work with column order and other column configuration - it's a normal column. If you put it third in the columns array, that's where it's going to be displayed.

Defining a view with grouping - one group column configured, but groups by 2 fields
defaultState = {
  view: {
    currentViewId: 'firstView',
    views: [
      {
        id: 'firstView',
        label: 'My View',
        columns: [
          { id: 'group', groupBy: ['language','license'] }
          { id: 'name', },
          { id: 'license' },
          { id: 'stars', editable: false }
        ],
      },
    ],
  },
};

Types of Row Grouping

There are two ways a row group column can be defined:

  • with the groupBy be an array of existing column ids - the group rendering strategy is single - meaning there's only one group column generated, even if there may be multiple columns to group by. In this case, you can have only one group column defined in the view, though it can have many groupBy items.
  • with the groupBy be the id of a column - the group rendering strategy is multiple - so a column is generated for each group column, as the group column will contain the grouping for only one field.

Note

Group columns work the same in both table and pivot views - they support the same properties and have the same behavior.

Row Grouping with single rendering strategy

This is the first case described above - you only have a group column defined in the view, but that group column is configured with groupBy to be an array, with one or more column ids referenced in this array.

Only one column is generated in the underlying DataGrid (hence the name - single rendering strategy) - but this column will display grouping by all the fields specified in the groupBy.

Row grouping with single rendering strategy - group by 2 fields
defaultState = {
  view: {
    currentViewId: 'firstView',
    views: [
      {
        id: 'firstView',
        label: 'My View',
        columns: [
          { id: 'group', groupBy: ['language','license'] }
          { id: 'name', },
          { id: 'license' },
          { id: 'stars', editable: false }
        ],
      },
    ],
  },
};

Note

If you want to have this rendering strategy, specify an array (e.g: groupBy: ["language"]) even when you group by a single column.

When a single column is configured in the groupBy array, it doesn't make any difference in the columns generated in the underlying DataGrid, but adding a new column to the grouping from the View Editor UI will work as expected and keep the current rendering strategy.

Row Grouping with multiple rendering strategy

This is the second case described above - you can have multiple group columns (hence the name - multiple rendering strategy) defined in the view and each one is configured with groupBy as a string, more specifically, the id of an existing column.

Row grouping with multiple rendering strategy - group by 2 fields
defaultState = {
  view: {
    currentViewId: 'firstView',
    views: [
      {
        id: 'firstView',
        label: 'My View',
        columns: [
          { id: 'language-group', groupBy: 'language', label: 'Language' }
          { id: 'license-group', groupBy: 'license', label: 'License' }
          { id: 'name', },
          { id: 'stars', editable: false }
        ],
      },
    ],
  },
};
Demo for both grouping types - both single and multiple rendering strategies
Fork

View Private Entities

Mirroring the structure in globalEntities, each view can contain a privateEntities properties.

Note

This means that a view can have its own privateEntities.availableColumns

In this case, the View can reference any column available in either global or private entities.

Also, in the view editor, the user will be able to see the list of all columns available to the view.

Views with private columns
Fork

The view with label Table View has 3 private columns that are only available to that view.

  • closed_issues_count
  • open_pr_count
  • closed_pr_count

Open the view editor to see the list of columns available. If you switch to the Grouped View, those columns are not available.

Column sorting

For specifying the sorting, the view has view.columnSorting property, which is an array that can have items of the following shape:

  • columnId - the id of the column to sort by (can even be a column not currently visible in the view)
  • dir - 'desc' or 'asc' - the direction of the sorting.
View sorting
import { type AdaptableTableView } from '@adaptabletools/adaptable-infinite-react';

const views: AdaptableTableView[] = [
  {
    id: 'tableView',
    label: 'Table View',
    columnSorting: [
      {
        columnId: 'language',
        dir: 'asc',
      },
      {
        columnId: 'stars',
        dir: 'desc',
      },
    ],
    columns: [
      { id: 'name' },
      { id: 'language' },
      { id: 'stars', editable: false, label: 'GH Stars' },
      { id: 'closed_issues_count' },
      { id: 'open_pr_count' },
      { id: 'closed_pr_count' },
    ],
  },
];
Sorting views
Fork

The view with label Table View has the following sorting defined:

  • language, in ascending order
  • stars, in descending order

Open the view editor to see the list of columns available. If you switch to the Grouped View, those columns are not available.

Single vs multiple column sorting

Views have a boolean singleColumnSort property - if set to true, users are only allowed to sort by a single column at a time (in the UI).

When singleColumnSort is not specified or when it's set to false users are allowed to sort by multiple columns at once by Cmd/Ctrl+clicking the column header. This action adds the clicked column to the current sorting order. When singleColumnSort is true, the user cannot Cmd/Ctrl+click to add a column to the sorting order, but rather clicking a column header replaces the current sorting order with the clicked column.

Note

singleColumnSort is only a UI feature - it does not forbid you from passing multiple items in the view.columnSorting array in code.

Users can change the singleColumnSort setting in the view editor.

The default value for singleColumnSort is false.

Sorting views with single column sort
Fork

The view with label Table View has can only ever sort by one column. This is because singleColumnSort is set to true in the view definition.

In this example, the language column is sorted in ascending order.

Custom sort order via column.sortType

Columns are sorted by their dataType by default. If you want to sort a column differently, you can specify a sortType property in the column definition. This needs to be one of the values defined in a sort type in globalEntities.sortTypes.

Defining and using custom sort types
defaultState = {
  globalEntities: {
    availableColumns: {
      id: { field: 'id', dataType: 'number' },
      name: { field: 'name', label: 'Name', dataType: 'text' },
      language: {
        field: 'language',
        dataType: 'text',
        sortType: 'reverse',
      },
      license: { field: 'license', dataType: 'text' },
    },
    sortTypes: {
      reverse: {
        label: 'Reverse sort for text columns',
        compare: (a: string, b: string) => {
          return b.localeCompare(a);
        },
      },
    },
  },
};

The above snippet configures the language column to be sorted in reverse order.

Custom sort type defined for a column
Fork

The language column has a custom sortType, which sorts the column in reverse order. Also, it's sorted in ascending order by default, which actually sorts the column in reverse order, because of the custom sort type.

Note

Column type defaults and column defaults can also specify a sortType property.

Defining and using custom sort types
defaultState = {
  globalEntities: {
    availableColumns: {
      id: { field: 'id', dataType: 'number' },
      name: { field: 'name', label: 'Name', dataType: 'text' },
      language: {
        field: 'language',
        dataType: 'text',
        columnType: 'custom-text',
      },
      license: { field: 'license', dataType: 'text' },
    },
    columnTypeDefaults: {
      'custom-text': { sortType: 'reverse' },
    },
    columnDefaults: {
      sortType: 'reverse',
    },
    sortTypes: {
      reverse: {
        label: 'Reverse sort for text columns',
        compare: (a: string, b: string) => {
          return b.localeCompare(a);
        },
      },
    },
  },
};

Column aggregations

You can specify aggregations for columns in a view. This is useful when the view is grouped by a column.

You can either specify an aggregation for a column in the column definition that's in globalEntities.availableColumns in state, or, you can specify it in the view definition.

In both cases, use the aggregation property to define the aggregation function.

Defining column aggregations in column definitions in global entities
defaultState = {
  globalEntities: {
    availableColumns: {
      id: { field: 'id', dataType: 'number' },
      name: { field: 'name', label: 'Name', dataType: 'text' },
      language: { field: 'language', dataType: 'text' },
      license: { field: 'license', dataType: 'text' },
      stars: {
        field: 'github_stars',
        editable: true,
        dataType: 'number',
        aggregation: 'sum',
      },
    },
  },
};
Defining column aggregations in the columns in the view
const views: AdaptableTableView[] = [
  {
    id: 'groupedView',
    label: 'Grouped View',
    columns: [
      { id: 'language-group', groupBy: ['language'], label: 'Group' },
      { id: 'name' },
      { id: 'stars' },
      { id: 'open_pr_count', aggregation: 'sum' },
      { id: 'license' },
      { id: 'homepage' },
    ],
  },
];

When the view is grouped, the column will show the aggregation value in the group rows.

Available aggregations

  • for dataType = number
    • sum
    • avg
    • min
    • max
    • count
    • distinct
  • for dataType = text
    • count
    • distinct

Note

false is also a valid value - useful when the column definition has an aggregation but you want to override that when you reference the column in the view.

Grouped view with aggregation
Fork

This example shows a view grouped by language and with a sum aggregation on both the github_stars column and the Open PRs column.

In addition, it also has a default sorting on the github_stars column (in ascending order).

Custom aggregation functions

Coming soon - please get in touch with our Support Team to let us know what you'd need.

Saving Views

When a view is updated (columns are resized, reordered, row-grouped, etc), the state is updated as well.

See our docs on Adaptable State to understand how views are managed in state.

Hint

If Adaptable is being used via the Provider component, useAdaptableState will provide access to the latest state of the component:

import { Adaptable } from '@adaptabletools/adaptable-infinite-react';

function App() {
  return <Adaptable.Provider {...}>
    <YourCmp> // <--- has access to useAdaptableState()
    <Adaptable.UI />
  </Adaptable.Provider>

Using hooks when rendering the component gives you direct access to the Adaptable State.