Working with columns

There are 2 places where columns are defined:

  • in the availableColumns property of the globalEntities object in the state (or in privateEntities in view). We call these column definitions.
  • in the columns property of a view. We call these column references.

Column definitions

Column definitions can either be global or private.

Global column definitions

This is the most common way of defining columns.

You define available columns in globalEntities.availableColumns in state. The columns you define in the globalEntities are available to all views.

Defining available columns in globalEntities.availableColumns in state
<Adaptable.Provider
  primaryKey="id"
  adaptableId="Adaptable View Demo"
  data={[...]}
  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.stars * 10,
          dataType: 'number'
        }
      }
    },
    view: {
      currentViewId: 'tableView',
      views: [
        {
          id: 'tableView', label: 'Table View',
          columns: [
            { id: 'name' }, // reference the `name` column
            { id: 'stars', editable: false },
            { id: 'language' },
          ],
        }
      ]
    },
  }}
>
</Adaptable.Provider>

Private column definitions

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.

Column references

Another important concept is a column reference - it's basically the columns we declare in views (more specifically, in view.columns).

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 the available columns.

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

Column properties

All the properties listed below are available in the column definition:

  • dataType (mandatory) - one of 'number' | 'text' | 'boolean' | 'date' | 'array'
  • field - the name of the property in the data object
  • valueGetter - ({ data }) => any - a value getter function for the column
  • expression - the AdaptableQL expression used to calculate the column value.

A column needs to have a dataType and at least one of the field, valueGetter or expression properties defined. The above properties cannot be overriden in a column reference (ie. when columns are listed in the view.columns property) as they are core to what the column actually is.


The properties listed below are available in both column definitions and column references:

  • aggregation - one of

    • for dataType = number
      • sum
      • avg
      • min
      • max
      • count
      • distinct
    • for dataType = text
      • count
      • distinct
    • 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.
  • aggregatable - boolean - if this column can be aggregated

  • checkboxSelection - boolean - whether to show a checkbox for selection in this column (only works if row selection is enabled)

  • columnType - string | string[] | null - a column type (column types can be used for giving more columns a common set of properties; can also be used for simply "tagging" columns)

  • components - object - an object with custom components for the column. See Infinite Table column components for the supported components.

  • editable - boolean - if this column has editing enabled

  • exportable - boolean - if this column will show up in exported data

  • filterable - boolean - if this column can be filtered

  • flex - number - a flex value for the column (works similarly to the flex CSS property) - this will make the column grow or shrink depending on available space. If not specified, the column will not be flexed but have a fixed width.

  • label - string - a label for the column. If not specified, the column id will be used.

  • maxWidth - number - the maximum width of the column

  • minWidth - number - the minimum width of the column

  • pivotable - boolean - if this column can be pivoted by

  • renderValue - () => ReactNode - a custom renderer for the column value - see Infinite Table column renderValue for details

  • renderHeader - () => ReactNode - a custom renderer for the column header - see Infinite Table column renderHeader for details

  • rowGroupable - boolean - if this column can be used for row grouping

  • sortable - boolean - if this column can be sorted

  • visible - boolean - if this column is visible by default

  • width - number - the initial width of the column

Note

Besides the dataType, and field/valueGetter/expression properties (at least one of those 3 needs to be defined), all other properties are optional and also they can be overriden in the view column references.

Column defaults

You can configure the default values for column properties in your state globalEntities.columnDefaults and have them applied as the default values for all columns.

Using column defaults
<Adaptable.Provider
  primaryKey="id"
  adaptableId="Adaptable Demo"
  data={[...]}
  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', dataType: 'number' },
      },
      columnDefaults: {
        editable: true,
        minWidth: 100,
        flex: 1
      },
    },
    view: {
      currentViewId: 'tableView',
      views: [
        {
          id: 'tableView',
          label: 'Table View',
          columns: [
            { id: 'name' },
            { id: 'stars', editable: false },
            { id: 'language' },
          ],
        },
      ],
    },
  }}

Note

Besides the mandatory properties in a column:

dataType and field/valueGetter/expression (at least one of those 3 needs to be defined).

all properties can be specified in the columnDefaults object.

Obviously if inside the view, a specific column overrides some properties, the overrides will win over the defaults.

Fork

This example sets the following defaults:

  • minWidth to 100
  • flex to 1
  • editable to true

The github_stars column overrides the editable property to false.

Column types

Column types can be used in two major ways:

  • to give a common set of properties to a group of columns
  • to "tag" columns with a certain type - and use those as scopes for other features (eg. styled cells, flashing cells, alerts, etc)

Using columnType for common properties

A column can have one or more column types, or even no column type.

If a column has a column type, the properties from the column type will be applied to the column, if those are not overriden by the column.

If a column has an array of column types, the properties from the column types will be applied to the column in the order they are defined in the array. Overriding properties will still work.

A column can opt out of a column type by setting the column type to null.

Using column types
const defaultState = {
  globalEntities: {
    availableColumns: {
      id: { field: 'id', dataType: 'number', columnType: 'not-resizable-or-editable' },
      name: {
        field: 'name',
        label: 'Name',
        dataType: 'text',
        columnType: 'not-resizable-or-editable',
      },
      language: { field: 'language', dataType: 'text' },
      stars: { field: 'github_stars', dataType: 'number', columnType: ['count', 'important'] },
      open_issues_count: {
        field: 'open_issues_count',
        dataType: 'number',
        label: 'Open Issues',
        columnType: 'count',
      },
      closed_issues_count: {
        field: 'closed_issues_count',
        dataType: 'number',
        label: 'Closed Issues',
        columnType: 'count',
      },
    },
    columnTypeDefaults: {
      'not-resizable-or-editable': {
        resizable: false,
        editable: false,
        pinned: true,
        width: 100,
        maxWidth: 100,
        minWidth: 100,
      },
    },
    columnDefaults: {
      resizable: true,
      editable: true,
      flex: 1,
      minWidth: 200,
    },
  },
};

Note

When using column types, it's not mandatory to define defaults for them. If you don't define defaults (via globalEntities.columnTypeDefaults), the columns will simply not have those properties.

Using column types to apply column properties
Fork

In this demo, the id and name columns have a columnType of 'not-resizable-or-editable'. We then define some defaults for that column type:

const columnTypeDefaults = {
  'not-resizable-or-editable': {
    resizable: false,
    editable: false,
    pinned: true,
    width: 100,
    maxWidth: 100,
    minWidth: 100,
  },
};

Using columnType for tagging the column

Another valid use-case for specifying the columnType for a column is to use it as a scope for other features.

For example, you might want to tag some numeric columns with a currency column type, and then use that column type as a scope for styled cells in order to format the column values in a certain way.