Columns
When working with tables, you are going to need some columns! The easiest way to define them in the React component for DataTables is with the <Column> component that the package exports. When installing the package you might have noticed that there is a named Column property you can import along with the main <DataTable> component:
import DataTable, { Column } from 'datatables.net-react';
The <Column> component can be a child of the host <DataTable> and defines how the column should be displayed.
When using <Column> you will typically specify a title and data property, which tells DataTables what the title text for the column should be, and where to get the data to display in the column for each row. These map to the columns.title and columns.data initialisations options for DataTables.
Consider this simple example:
function App() {
return (
<DataTable ajax="/data.json">
<Column title="Name" data="name" />
<Column title="Position" data="position" />
<Column title="Office" data="office" />
<Column title="Extn." data="extn" />
<Column title="Start date" data="start_date" />
<Column title="Salary" data="salary" />
</DataTable>
);
}
Here the table is instructed to show six columns, based on the data loaded from data.json.
Example: You can see this example here.
Properties
The <Column> component makes the following properties available:
data- The data point that should be used for reading the data to display in the column from the row's data source. Maps tocolumns.data.footer- The text to show in the table footer for the column. Maps tocolumns.footer.options- Object of options for the columns. Can take any of the properties or values from the DataTables column configuration object.render- Define the rendering function used to display the data. Note that this cannot be used at the same time as a child component (see below).title- The text to show in the table header for the column. Maps tocolumns.title.
The data, footer and title options are provided as properties for the component as a convenience, but they could equally be defined as part of the options object if you prefer. If both are defined, the property value will be used.
Column properties
The options object offers a wealth of options to be able to control a column. For example columns.searchable controls if a column's contents will be included in the search data set for the column while columns.orderable define if a column can be ordered by the end user.
If we consider those two options and want to disable them for a specific column, you might use:
<Column title="ID" data="id" options={{orderable: false, searchable: false}} />
Child components
You will likely wish to show React components inside a DataTable's cells at some point. To do this the <Column> component can have a child function defined which returns a JSX element (or even a plain value if you prefer). This function will be called for each cell in the column that DataTables needs to display.
For example, if you wish to have a <Button> component in each cell, with data based on the value pointed to by the data property, use:
<Column title="Buttons" data="id">
{id => <Button text={id} />}
</Column>
There are a number of important points to make here - firstly, the value passed in is the value that the data property points to in the row's data source. In the example above this is a property called id.
Secondly, this construct interacts with DataTable's orthogonal data. Specifically, the function that returns the JSX is assigned to the display property, so DataTables will only require the JSX to be rendered when it is going to display that cell. For all other data types (e.g. ordering, search and type detection) the original data value will be used.
Example: TODO
Top level columns option
You might have noticed in the <DataTable> documentation that it provides a columns property. This maps to the columns array that can be defined as part of the DataTables initialisation. As such, if you prefer, you can define columns using that array. The initialisation that matches the first example above is:
function App() {
const columns = [
{ title: 'Name', data: 'name' },
{ title: 'Position', data: 'position' },
{ title: 'Office', data: 'office' },
{ title: 'Extn', data: 'extn' },
{ title: 'Start date', data: 'start_date' },
{ title: 'Salary', data: 'salary' }
];
return (
<DataTable ajax="/data.json" columns={columns} />
);
}
Note that here there is no need to use the <Column> component in this case as the columns are fully defined by the columns property. Typically you would use one or the other, not both (although if both are defined, they will be merged).
Slots
If you use the columns property, you may still want to use JSX to display interactive React components in the table cells. For this the <DataTable> component supports the ability to define a "slot" function for each column. This function is passed data about the cell that is being rendered and takes a React element / JSX as a return.
This is done using the slots property for the <DataTable> component. It is an object whose keys are either column indexes or column names (columns.name) - these keys are used to identify which column the slot should apply to. Each slot value is a function that can take two or three parameters.
In the following a <Button> component is rendered into column index 0 (i.e. the first column):
<DataTable
slots={{
0: (data, row) => (
<Button onClick={doClick}>
Click me!
</Button>
)
}}
>
If a slot function expects two parameters they are:
- Cell data
- Row data
DataTables will then automatically attempt to extract the ordering and search data from the React element that is returned.
If a slot function expects three parameters they are:
- Cell data
- Data type (
sort,type,filter,display) - Row data
If you are already familiar with DataTables, you might recognise these parameters as those used for rendering functions and orthogonal data. It allows you to return specific data that DataTables use for ordering, search and type detection. The display type expects the React element / JSX in the return.
Tic-tac-toe
As an example of this in action, let's take our reactive data example from above, and say that we want to use the <Square> component to display in the table for each move, rather than the string X / O.
That might look something like this:
<DataTable
slots={{
1: (data) => {
return <Square val={data} />;
}
}}
>
Note how JSX is used for the function return based on the data passed into it and 1 is used as the column index identifier for the column to apply this index to.
Example: Using slots to display a React component in a column