API
DataTables and its extensions have an extensive API which can be used to access the data contained in the table and otherwise manipulate the table after initialisation has completed. The DataTables API is designed to reflect the structure of the data in the table, and the ways that you will typically want to interact with the table. As such the API is composed of six key areas for working with the table and its data:
- Tables
- Columns
- Rows
- Cells
- Core
- Utilities
Extensions and plug-ins may also add additional methods to the API exposing the features and functionality that they add to the DataTable.
For a full list of the methods that are available in the API, please refer to the API reference section.
Terminology
In order to keep the documentation of the API succinct, a number of terms are used to describe, or refer to, aspects of the API. These are defined here:
- Instance - an instance of the API is a single object instance which refers to a specific set of DataTable tables (i.e. is the the result of
new DataTable.Api()). - Result set - the data held by the API instance. DataTables API instances are "array like" in that they hold data in the same way as a plain Javascript array (and thus can be accessed using array
[]notation) and have many of the same methods available (sort()andpush()for example). - Context - the context of an API instance describes the DataTables that the API instance has a link to. Each API instance can refer to one or more DataTables tables, with the ability to act upon those tables (see below for further information).
Accessing the API
A new DataTables API instance is created when you use use the DataTable constructor - e.g.:
const table = new DataTable( selector, options );
It is also possible to create a new API instance for an existing DataTable using the DataTable.Api constructor:
const table = new DataTable.Api( selector );
The result from each is an instance of the DataTables API object which has the tables found by the selector in its context.
Chaining
The DataTables API makes extensive use of chaining, with many, but not all, of the DataTables methods returning the API instance itself, so you can immediately call another API method. For example:
const table = new DataTable('#myTable');
table.search( 'Fiona' ).draw();
This makes use of two different API methods, search() and draw(), on a single line. It could equally be written as:
const table = new DataTable('#myTable');
table.search( 'Fiona' );
table.draw();
The functionality is identical in this case, but chaining can allow for more succinct and expressive code.
The DataTables API isn't a simple flat object, rather the methods available on the chain depend on the methods that were called in previous steps. For example, the ajax.json() method gives you access to the latest JSON data from an Ajax call DataTables has made - in this case the json() method is a child of the ajax property. Likewise, the columns() (and other data manipulation methods) provide their own chaining child methods. For example, columns().visible(). This allows the API to be very expressive in terms of how you access data, with methods relating to what has been called before.
All top level methods of the API will always be available, at all levels of nesting of the API. For example draw() is a top level method, but it can be called after a row is removed from the table: table.row( selector ).remove().draw();.
Please note that not all methods will return an API instance for chaining. In some cases, returning the API instance for chaining wouldn't be appropriate, such as cell().node() to get a td / th element. The API reference documentation contains full details for each method and what it will return.
Multiple tables
DataTables API instances can refer to multiple tables in their context. The API treats each table in a context as the same. For example:
const tables = new DataTable.Api('table.data');
tables.page( 'next' ).draw( false );
This code will select all tables in the document with the class data and jump them all to their next page of data display (using page()).
Equally, an API instance can refer to a single table if required, simply by altering the CSS selector used to create the API instance: new DataTable.Api('#myTable') will create an API instance with a single table in its context for example.
Plural / Singular
When working with the API you will notice that the methods make extensive use of plural and singular terminology. Although this is relatively unusual in an API, it is done to reflect the way that you access the data in the table - for example rows().data() will return an API instance with the data for the selected rows in its result set (i.e. like an array), while row().data() will return the data for just that row. This makes working with the API much more intuitive as you will always get the result you expect.
To be clear, in English (for our international users):
- Singular === 1
- Plural > 1
So if you want to use one of the selector methods to select multiple items, use the plural form of the method. If you want to select a single specific item, use the singular form.
Example - column filter
API reference documentation contains an example for each API method, along with a detailed description of what it does, what it returns and what parameters it will accept; but let's form the concepts described above into a detailed, line-by-line example of how the DataTables API can be used. In this case we create a select element in the footer cell of each column in the table, which contains the data from that column and will be used for searching the table.
const table = new DataTable('#myTable');
table.ready(() => {
table.columns().every(function () {
let column = this;
// Create select element
let select = document.createElement('select');
select.add(new Option(''));
column.footer().replaceChildren(select);
// Apply listener for user change in value
select.addEventListener('change', function () {
column.search(select.value, {exact: true}).draw();
});
// Add list of options
column
.data()
.unique()
.sort()
.each(function (d, j) {
select.add(new Option(d));
});
});
});
- Line 1 - Create a new with a single table in its context
- Line 3 - Use the
ready()method to wait for the table to become ready. While in this case the table initialisation is synchronous, soready()isn't strictly necessary, it can be good practice to use it to allow for async initialising when usingajax. - Line 4 - Use
columns().every()to execute a function for each column in the table. - Line 5 - Alias
thisto a descriptive named variable. Note that this function is not a "fat arrow" function, as the scope of the function provides column specific methods (column()). - Lines 8-10 - Create a new
selectelement and attach an initial empty option (to represent no filter). - Line 13 - Adding an event listener to the
selectso we know when the end user changes a value. - Line 14 - Apply the selected value to the table. This uses
column().search()for the search and chainsdraw()to have the table's display update with the filtered data. - Lines 18-24 - This block shows off the power of chaining. We use
column().data()to get the data from the target column. Thenunique()andsort()to make sure there is only a single entry for each value, and to make sure that the values are ordered sensibly. The last part will create newoptionelements for each value and attach them to theselect.
This example can be seen running live here.
As you can see, the DataTables API is extremely flexible, and provides a wide range of options for accessing and manipulating the table. Please see the API reference documentation for a full list of the methods that are available. Furthermore, plug-ins such as Editor can extend the API with custom methods such as row().edit() and cell().edit() among others.