Renderers

There are occasions when the data source for the table's rows does not contain the value that you would want to display in the table. You may wish to transform it to a different representation (such as a time stamp into a human readable format), combine data points (first and last names, perhaps) or perform some computation on the value (maybe calculating margin from turnover and expense values).

This transformation of the original data into the value that will be shown in the DataTable is called rendering in DataTables' terminology and is performed using the columns.render option.

Data rendering

The primary advantage of using a data renderer in DataTables is that you can modify the output data without modifying the original data. The columns.data method can be used to get and set data, but the set operation adds significant complexity and it is recommended that the columns.data option be used simply to point to the original representation of the data and allow a renderer (columns.render), which is read only, to transform the data.

columns.render can be utilised in a number of different ways:

  • As a function to transform data
  • As a string to select data from an object

Functions

Using columns.render is the most common method as it provides absolute control over the data that will be displayed to the end user (this is a regular Javascript function, so you can do virtually anything you wish with the data).

The function is passed in three parameters:

  1. The data that is pointed to by columns.data. If columns.data is null, null will be the value given here.
  2. The data type being requested by DataTables - this allows the function to support orthogonal data.
  3. The original and full data object or array for the row.

The value that is returned from the function is whatever DataTables will use for the data being requested (display, ordering, search, etc).

Consider for example the following data structure which contains the data for a row:

{
    "product": "Toy car",
    "creator": {
        "firstName": "Fiona",
        "lastName": "White"
    },
    "created": "2015-11-01",
    "price": 19.99,
    "cost": 12.53
}

Adding formatting

In our DataTable, if we wish to have a column that shows the price, it is relatively common to wish to prefix it with a currency sign. In this case we use a dollar sign (see also the built-in number renderer below which provides advanced formatting options):

{
    data: 'price',
    render: function ( data, type, row ) {
        return '$'+ data;
    }
}

Joining strings

In our DataTable if we wish to have a single column that shows the full name of the creator we can concatenate strings using the following columns definition (note in particular how the create object is passed in as the first parameter due to its assignment using the columns.data option):

{
    data: 'creator',
    render: function ( data, type, row ) {
        return data.firstName +' '+ data.lastName;
    }
}

Transforming data

For another column we wish to display the created value, but formatted using the US standard MM-DD-YYYY formatting. This can be done simply by splitting the string and rearranging the component parts. We also wish for the date to be sortable, and since DataTables has built in support for ISO8601 formatted string (the original format), we wish to perform the transformation only for the display and filter data type - see orthogonal data for more):

{
    data: 'created',
    render: function ( data, type, row ) {
        var dateSplit = data.split('-');
        return type === "display" || type === "filter" ?
            dateSplit[1] +'-'+ dateSplit[2] +'-'+ dateSplit[0] :
            data;
    }
}

Computing values

Finally, to create a margin column from the price and cost fields we can use a function to compute the required values - note that in this case columns.data is null - as a result the first parameter passed into the columns.render method is also null, but the third parameter provides access to the original data source object, so we can continue use the data from there:

{
    data: null,
    render: function ( data, type, row ) {
        return Math.round( ( row.price - row.cost ) / row.price * 100 )+'%';
    }
}

Strings

A less common option for formatters is as a string to simply point at the data that should be used in the table. This is similar to the way that columns.data is often used, although keep in mind that the renderer will only have access to the data pointed to by columns.data rather than the full row.

Continuing the examples using the JSON data structure from above, consider a column that should show the first name of the creator:

{
    data: 'creator',
    render: 'firstName'
}

There is no advantage to this method over simply using data: 'creator.firstName' in the example presented here, but if you have complex data with orthogonal data included in the data source object, this can sometimes be useful.

Built-in helpers

DataTables has a number of built in rendering helpers that can be used to easily format data - more can be added using plug-ins (see below):

  • date - formatting dates (since 1.12)
  • datetime - formatting date times (since 1.12)
  • number - for formatting numbers
  • text - to securely display text from a potentially unsafe source (HTML entities are escaped)
  • time - formatting times (since 1.12).

The built in rendering helpers can be accessed under the DataTable.render object (since 1.11) or $.fn.dataTable.render (which is an alias to the same object). They are functions (allowing options to be passed into them) which should be immediately executed and their result assigned to the columns.render method. This might sound a little complicated, but it simply means you would use something like the following:

{
    data: 'price',
    render: DataTable.render.number( ... )
}

Date and time helpers

We'll discuss the date, datetime and time helper functions together, as they all share the same API. These renderers can be used to:

  • Format an ISO-8601 string into a locale aware display string without any additional software,
  • Format an ISO-8601 string to a custom format via either Moment.js or Luxon,
  • Transform between a custom format in the data and another custom format for display (again using Moment.js or Luxon).

The date, datetime and time helper functions have the following function signatures:

DataTable.render.datetime()                  // Display a locale aware date / time from an ISO-8601 string
DataTable.render.datetime(to)                // Display a custom format date / time from an ISO-8601 string
DataTable.render.datetime(to, locale)        // Display a custom format date / time with a given locale
DataTable.render.datetime(from, to, locale)  // Transform from one custom format to another, with a given locale.

where:

  • to is the format that you wish to be shown in the DataTable. Note that if this option is used, you must include either Moment.js or Luxon on your page. Each library has its own formatting token support. Please refer to their documentation for the formatting options available (Moment.js documentation | Luxon).
  • locale is the locale to be passed to Moment.js or Luxon. If you use this option and it isn't the default en, you will need to be sure to load that locale for the library you are using.
  • from the date / time format that should be parsed from the column. This also uses the Moment.js and Luxon parsing tokens, and note that the parsing is strict - it must exactly match the format of your date.

Examples for Date / time handling in DataTables are available here.

Number helper

The number helper provides the ability to easily format, you guessed it, numbers! When dealing with numbers, you may often wish to add formatting such as prefix and postfix characters (currency indicators for example), use a thousands separator and specify a precision for the number. This is all possible with the number helper.

This number helper function has the following function signature:

DataTable.render.number()                                                // Locale aware number display (since 1.12)
DataTable.render.number(null, null, precision, prefix, postfix)          // Locale aware display with decimal places, prefix and postfix (since 1.12)
DataTable.render.number(thousands, decimal, precision, prefix, postfix) // Thousands and decimal specified

where:

  • thousands is the character to use for the thousands separator (can be null in which case a locale aware separator is used)
  • decimal is the character to use for the decimal character (can be null in which case a locale aware character is used)
  • precision is the floating point precision - 0 for integers, 1 for a single decimal place, etc (optional)
  • prefix is a prefix string (optional)
  • postfix is a postfix string (optional)

For example, to display the price data point from the data structure shown above in the format $19.99 we would use:

{
    data: 'price',
    render: DataTable.render.number( null, null, 2, '$' )
}

Note that null is used for the thousands and decimal characters. This is recommends as it will allow DataTables to display the number is a format suitable for your end user automatically.

Additionally, if the number helper encounters a value which is not a valid number (either number or string that contains a number) it will return the value after escaping any HTML entities in it (to help protect against potential security attacks).

An example of the number renderer is available here.

Text helper

The text helper will ensure that any potentially dangerous HTML in the source data will not be executed by escaping the HTML entities. This can be useful if the data being loaded may come from a potentially untrusted data source and can help mitigate XSS attacks.

The text helper doesn't take any parameters making its use simply:

{
    data: 'product',
    render: DataTable.render.text()
}

Custom helpers

Rendering helpers are simply functions which are attached to the DataTable.render object (which can also be access through $.fn.dataTable.render) to make them easily accessible from a single location. These functions must return a function that will operate with the columns.render method.

Consider for example the following simple plug-in that will truncate text after a given number of characters and show ellipsis if the string is longer that the number of characters allowed:

DataTable.render.ellipsis = function ( cutoff ) {
    return function ( data, type, row ) {
        if ( type === 'display' ) {
            var str = data.toString(); // cast numbers

            return str.length < cutoff ?
                str :
                str.substr(0, cutoff-1) +'&#8230;';
        }

        // Search, order and type can use the original data
        return data;
    };
};

We can then use that in our DataTables column definitions:

{
    data: 'description',
    render: DataTable.render.ellipsis( 10 )
}

A more comprehensive ellipsis rendering helper is available in the DataTables plug-ins repository with word break and HTML escaping control. Others will be available in the same repository as they are developed.

Contributing

If you have written a rendering helper that you would like to share with the DataTables community, first of all, thank you! Rendering helpers can be committed to the Plug-ins repository and pull requests are very welcome. Alternatively, if you don't have a GitHub account, post your code in the DataTables forums.