DEV Community

Tom
Tom

Posted on

Sort Carbon's DataTable with a backend API

Carbon's DataTable supports client-side sorting out of the box. If you need to call a web service to sort your data, it gets a little hackier. This is how I solved it:

First add the isSortable property to DataTable:

<DataTable
  isSortable
  {...rest}
>
Enter fullscreen mode Exit fullscreen mode

Then add the following properties to TableHeader:

<TableHeader
  onClick={() => {
    /** Retrieve data from server */
  })}
  isSortHeader={Boolean}
  sortDirection={'ASC' | 'DESC'}
  >
  {header}
</TableHeader>
Enter fullscreen mode Exit fullscreen mode

Please note I use 3 undocumented features of Carbon here:

  1. The onClick handler is used to override the default behavior (client-side sorting) and can be used to retrieve server data.
  2. The sortDirection property is used to display the correct arrow on the sorted column header.
  3. isSortHeader indicates that the current column is the one that is sorted.

As these properties are not documented they might change at any time without warning.

Bonus: Make sortable part of the Carbon headers object

Carbon uses a header object to generate table headers, example:

const headers = [
  {
    key: 'name',
    header: 'Name',
  },
  {
    key: 'status',
    header: 'Status',
  },
];
Enter fullscreen mode Exit fullscreen mode

We can extend this object to indicate whether a certain column is sortable:

const headers = [
  {
    key: 'name',
    header: 'Name',
  },
  {
    key: 'status',
    header: 'Status',
    sort: 'sortByStatus',
  },
];
Enter fullscreen mode Exit fullscreen mode

You can now use the sort key to determine if the column is sortable, and once clicked, which field the server should sort on. You'll end up with something like this:

{ headers.map( header => (
    <TableHeader
    {...getHeaderProps({
      header,
      isSortable: Boolean(header.sort),
    })}
    onClick={header.sort ? handleSort : undefined}
    isSortHeader={Boolean(header.sort)}
    sortDirection={getSortDirection(orderBy, header.sort)}
    >
    {header.header}
  </TableHeader>
))}
Enter fullscreen mode Exit fullscreen mode

Typescript

The headers object now gives a TypeScript error, because the sort doesn't exist. This can be solved as follows:

import { DataTableHeader } from 'carbon-components-react';

export interface DataTableHeader extends DataTableHeader {
  sort?: string;
}
Enter fullscreen mode Exit fullscreen mode

Discussion (0)