Orthogonal data
Data is complex. Not only will the data displayed in your tables have rules relating to how each data point corresponds to the others in your table, but also each data point itself can take multiple forms. Consider for example currency data; for display it might be shown formatted with a currency sign and thousand separators, while sorting should happen numerically and searching on the data will accept either form.
In DataTables we term this orthogonal data.
DataTables has four built-in data operations, each of which can potentially use an orthogonal (independent) data source. These four operations are:
display
- Display datasort
- Data used for orderingfilter
- Data used for searchingtype
- Type detection data
By default DataTables will use the same data for all four operations, but this can easily be modified using the data
and columns.render
initialisation option, or HTML 5 data-*
attributes.
Data source
Orthogonal data for a table can be provided through the data source array / object (note, objects are much easier to work with, since you don't need to remember array indexes!) as predefined values (typically this is done with ajax
loaded data or a Javascript provided data source), or they can be computed on-the-fly as they are needed.
Predefined values
If your data source has the orthogonal data that you wish to display already available in it, DataTables can make use of this directly by providing the columns.data
and / or columns.render
options as objects.
Consider for example the following date structure - note that the start_date
object has a nicely formatted display
property which will be used for display of the data in the table, but also a timestamp
property. This is useful in this case since the format selected for the date display is not easily sortable:
{
"name": "Tiger Nixon",
"position": "System Architect",
"start_date": {
"display": "Mon 25th Apr 11",
"timestamp": "1303682400"
},
"office": "Edinburgh"
}
To use the data in this format in the table we might use the following options for a columns
or columnDefs
column description:
{
data: 'start_date',
render: {
_: 'display',
sort: 'timestamp'
}
}
Note that the _
property must be defined when using columns.data
or columns.render
as an object. The _
property is the 'fallback' if a data option has not been defined (there is no display
option in the above object for example).
Computed values
If your data source does not contain pre-formatted orthogonal data, the columns.data
and columns.render
options can be provided as functions. These functions would be used to compute the data required for display.
For example, consider the following data structure:
{
"name": "Tiger Nixon",
"position": "System Architect",
"start_date": "1303682400",
"office": "Edinburgh"
}
Although the start date is in a nice format for the computer to use, it is virtually useless for humans. To resolve this we can compute the value to be displayed using columns.render
as a function - the columns.data
option tells the renderer what data to use:
{
data: 'start_date',
render: function ( data, type, row ) {
// If display or filter data is requested, format the date
if ( type === 'display' || type === 'filter' ) {
var d = new Date( data * 1000 );
return d.getDate() +'-'+ (d.getMonth()+1) +'-'+ d.getFullYear();
}
// Otherwise the data type requested (`type`) is type detection or
// sorting data, for which we want to use the integer, so just return
// that, unaltered
return data;
}
}
For further information on using renderers with DataTables, please refer to the renderer's manual page and the columns.render
reference documentation.
HTML 5
The above approach of using orthogonal data from a data source is great if you are ajax
loading the data, but it isn't so useful if your table already exists in HTML. For this, DataTables supports data-*
attributes, which can be used to hold information visible in the DOM, but not to the end user.
DataTables will automatically detect the following attributes on HTML cells:
data-sort
anddata-order
- for ordering datadata-filter
ordata-search
- for search data
For example, consider the following HTML table row:
<tr>
<td data-search="Tiger Nixon">T. Nixon</td>
<td>System Architect</td>
<td>Edinburgh</td>
<td>61</td>
<td data-order="1303682400">Mon 25th Apr 11</td>
<td data-order="3120">$3,120/m</td>
</tr>
Note that:
- The first column has a
data-search
attribute, allowing for a full name search in this case, while the display shows an abbreviated form. - The fifth column has a date which is not directly sortable, so
data-order
is used to provide the unix time representation for ordering. - The sixth column also uses
data-order
, in this case to provide a numeric form of a formatted number.
In order for the HTML 5 data-*
attribute detection and processing to work correctly, all cells in a column must have the same attribute available. Without this, DataTables will give a warning.
API interface
When DataTables reads data from an HTML table, by default it will read the data in each row into an array (although this can be customised with columns.data
). When the software detects orthogonal HTML5 attributes, it reads the information into an object, allowing multiple data points for each cell (if required).
If orthogonal data exists for a cell, the content of the cell (i.e. what the user sees) will be copied into a display
property. The HTML5 attributes are copied into properties with the same name as the attribute, but with an @
prefix.
If we continue the example from above, it will be read in using the following structure:
{
"0": {
"display": "T. Nixon",
"@data-search": "Tiger Nixon"
},
"1": "System Architect",
"2": "Edinburgh",
"3": "61",
"4": {
"display": "Mon 25th Apr 11",
"@data-order": "1303682400"
},
"5": {
"display": "$3,120/m",
"@data-order": "3120"
}
}
If you don't use the DataTables API to manipulate the data in the table, you'll never need to know the structure of the data. However, if you want to read the data back (e.g. using row().data()
) or add a new row of data (row.add()
) you need to make sure that you use the same data structure as DataTables read the data in as. Without that, you will get Requested unknown parameter errors.
To check the data structure DataTables is using for a row, use console.log( myTable.row(':eq(0)').data() );
to show the data for the first row in the table.