DataTables 2.0.0

DataTables CDN files for DataTables 2.0.0. This software was originally released on 15th February, 2024.

Release notes

It is finally here - DataTables 2! It is a big release with additions to the API, options, features for search, and many more. The full release notes are below, but let's highlight just a few points:

  • The new layout option can be used to position control elements around the table. It replaces the old dom parameter which was difficult to work with, particularly when using styling integration for Bootstrap or any of the other frameworks DataTables supports. layout works in the same way for all of them. This has made is possible to add a new option to the examples - you can now select which styling framework you want to see the example operate in! dom is still supported (note they are mutually exclusive, you cannot use both together) since it is widely used. But do yourself a favour, migrate away from it!
  • Multi-row headers and footers, plus column and row spanning cells in them, are now much better supported and integrated with the API. This now means that columns can share a header cell, and also that extensions such as Buttons can work with the complex headers to export that data.
  • Search is greatly improved with options for negative searching in the default search, boundary search, exact search, diacritic support and searching by functions. The new search.fixed() and column().search.fixed() methods greatly improve the options to provide custom search functions and for plug-ins to operate with DataTables' data.
  • Class names for the table control elements have been simplified and sanitized. They are now much easier to work with!

Along with everything that is new, there are also some legacy items which have been dropped. Specifically the legacy API (the Hungarian notation API) which was deprecated when the new API was added in 1.10. Additionally stripeClasses has gone (CSS's nth-child is used now) as have deferLoading which is no longer needed since search engines can index Javascript loaded data.

As a result updating should largely be pain free! I hate updating libraries myself, I know the pain it can cause, so I've spent a lot of effort trying to make this as smooth as possible, but there are some things that had to be updated to modernise DataTables. In particular, if you have any custom CSS using the DataTables classes, you will need to update based on that, and, as you will see there are a large number of changes, so it is possible that something has been missed. If so, please get in touch with a test case showing the issue.

New

  • Options
    • ajax can now be provided as an empty string to stop DataTables performing its initial Ajax call. Use ajax.url().load() to load data after the fact with the API. This can be useful for Ajax populated tables which need end user input (e.g. a search).
    • ajax.dataSrc can be given as an object to map all parameters for server-side processing (not just the data parameter).
    • caption option which can be used to set a table caption on initialisation
    • columnDefs.target / columnDefs.targets can now use a CSS selector to select column header cells to match against. Backwards compatibility is retained for the older string option of just using a class name (as a result of which this new selector option can not select on an element's name alone).
    • columns.footer option which can be used to create a column footer cell if there isn't one present in the DOM, or set the text of an existing cell.
    • columns.render can now return DOM elements for the display data type.
    • columns.render now supports the ability to use helper functions (defined on DataTable.render) using a pure JSON definition for the column. This is done by using an array of values where the first element in the array is the rendering function's name and the following elements are the parameters to pass to the function.
    • language.entries option. This can be used to instruct DataTables of the data type that the table is showing, so it can be reflected in the language strings shown to the end user.
    • layout option replacing dom. This is a much easier to use option to describe layout of the table's control elements. It also operates independently of the styling frameworks, making it much easier to port between them.
    • lengthMenu now easier to use, being an array of values, which can either be integers or a label / value object. The old 2D array form is still supported via the legacy integration.
    • order and order() can now accept a DataTables.Order data type, which in addition to the previous tuple that was used can also be given as an object containing a column index or column name upon which to apply the ordering to.
  • API
    • caption() and caption.node() API methods which can be used to get / set and otherwise manipulate a caption element for the DataTable.
    • column().header() and column().footer() (and their plurals) can specify a row index in the header / footer which the API method should return. This provides support for multi-row headers and footers via the API for the first time in DataTables.
    • column().init() and columns().init() methods to get custom configuration parameters for plug-ins.
    • column().orderable() and columns().orderable() which can be used to determine if a column (or multiple columns) are orderable by the end user, and optionally what ordering directions the column(s) can take.
    • column().order() and columns().order() can now be used as getters to determine if a column (or multiple columns) are currently being ordered on and in what direction if so.
    • column().render() and columns().render() methods. Basically the same as cells().render(), but slightly easier to use for fetching data on a per column basis.
    • column().title() and columns().titles() to get / set column titles, including support for multiple row headers. Note that this requires that DataTables wraps the text content of the header with a span element. It has a class of dt-column-title.
    • column().type() and columns().types() methods to get the data type for a column. Primarily designed for use by plug-in authors.
    • column().width() and columns().widths() methods to get the widths of the target columns. Primarily intended for plug-in and extension authors.
    • DataTable.feature.register() method, used to register new feature plug-ins for use with layout New examples: layout examples
    • DataTable.type(), DataTable.types() static methods which provide a way to manage the data types that are registered with DataTables and to add additional data types as required. This is effectively a harmonisation of the ordering, type detection and search pre-processing plug-ins that were available before. Old plug-ins will continue to work (although will not be addressable for manipulation unless the type detection function is named), but it is strongly encouraged that the new system should be adopted if you are working with custom data types. DataTables has been updated internally to use this these methods and the plug-ins will follow suit.
    • DataTable.util.debounce() method for creating debounced functions Updated: searchDelay now uses a debounce rather than a throttle.
    • DataTable.util.escapeHtml() method exposed for use by extensions and plug-ins. It is also settable and so can be replaced with an external library if needed for a particular application.
    • DataTable.util.stripHtml() method which can be used to satanize strings or to replace the built in (simple) sanitizer with a custom function.
    • DataTable.util.unique() method. Exposing a method we use internally for use by extensions and plug-ins. Update: Improve the performance of unique() through the use of Set if it is available in the browser. It is approx 200 times faster than the previous method! Old version is retained for older browsers that don't support Set and Array.from - but at some point that can be removed.
    • get() method which can be used to get the data underlying the DataTables API instance. This is basically the same as using the array syntax (e.g. [0] and .get(0) perform the same action. It is modeled after the jQuery $().get() method for consistency. Backwards compatibility: The eq() method will no longer return null if the selected context does not exist. Instead it returns an empty API instance. This change is made to make chaining methods without needing to add if conditions for catching conditions easier.
    • includes() method. This can be used in the same way as Array.prototype.includes() to determine if a particular value is in the API's result set.
    • processing() method which can be used to programmatically show and hide the processing indicator used by DataTables
    • ready() method to determine if the table is ready, or to execute a function when it becomes ready (immediately if it is already ready).
    • search() and column().search() can have the search configuration options passed in (a new DataTables.SearchOptions has been created and documented) rather than needing to pass in a long list of arguments. The old method signatures have been retained for compatibility.
    • search.fixed() and column().search.fixed(). These new functions provide a method to easily add complex search methods to DataTables, layer them and allow multiple search terms at a time.
    • state() will get the current state of the table regardless of the stateSave parameter.
    • state() can be used as a setter to set the state of the table programmatically from a state object (described in state()).
    • table().footer.structure() and table().header.structure() methods to get the table's header / footer structure
    • tables().every() API method to match rows, columns and cells.
    • trigger() method for use by extension authors to be able to trigger events in the same way as DataTables.
    • DataTable.versionCheck now accepts a second version string to be used as for the comparison rather than the DataTables version (although that is still the default if a second parameter is not passed in).
    • DataTable.util.diacritics() method exposing the diacritic stripping function we use, and providing the ability to replace it if you require.
  • Events
    • info event for when the table's information display is updated.
    • options event which can be used to modify the options passed into a DataTable, before DataTables does any processing of the options.
  • Search
    • Ability to use a function or regular expression as a search term for search(), column().search() and columns().search().
    • Boundary match option for search options
    • Exact match option for search options
    • Diacritic search support. You can now use DataTables search to look for accented characters without typing the accent. For example searching for creme brulee will match Crème Brulée in the table.
    • Smart search can now perform negative searching by prefixing the search string with a !. This will find all data which does not contain the word that follows. This also works with exact phrase matching (e.g. !"search term").
  • Ordering
    • Columns can now have three ordering states - asc, desc or data index order (specified by an empty string). The columns.orderSequence option has been updated to make use of this, so the third ordering on a column will now take it back to the index order, rather than returning to the first direction.
    • data-dt-order (attribute) can be applied to any cell or row in the header of the table to control if the order click listener is attached to the cell or not. It can also be used to control the ordering status icons.
    • Accessability - role=button applied to the <span> tag that wraps the table header for orderable columns.
    • Ordering extensions can now mix -pre formatters with -asc and -desc functions. Previously you could either use -pre with the built in sort test, or -asc/-desc for custom tests, but without the optimisation of a pre-formatter. You can now use -pre on its own, with -asc/-desc or just -asc/-desc on its own.
    • Ordering status (icons) is shown for a column, even if the end user cannot order the column themselves (i.e. columns.orderable has disabled the user's ability to order a column, but the developer has set ordering on the table).
    • Reworking of the ordering class names. The class names are now conditionally based on if a column header can be ordered, and if it is. They also respect that fact that ordering in a specific direction can be disabled.
    • Support for objects to describe ordering of the table, including the ability to specify the column name, not just the index
  • Ajax
    • "Loading..." text will be shown in the table for the first load when server-side processing is enabled.
    • null as the only response from an Ajax request is valid JSON, and it should represent an empty data set. DataTables will no longer throw an error, and correctly show an empty table.
    • A 204 response from an Ajax request, while it cannot contain valid JSON, is a valid response from the server. DataTables will no longer throw and error, and correctly show an empty table.
    • The columns.data property is now sent as part of the server-side processing request to the server for the order information. This saves needing to perform a lookup to get the data property from the columns array.
  • CSS:
    • Update DataTables default styling to use alpha channel to allow for any background colour
    • Apply an outline to the header cells on mouse hover to highlight that they are clickable for ordering. This also helps to delineate columns.
  • General
    • Ability to use a name (columns.name) as a target for column definitions (columnDefs.targets).
    • A layout function can return an instance that has a node method that will be used rather than being required to return the node (although that is also still supported).
    • Auto type detection class assignment. Class names are applied automatically to the table columns based on the detected column type. We now automatically right align number and date columns.
    • Child row nodes (either as a node, or in a jQuery object) can now be used as selectors in row() and rows().
    • Data types can have a renderer assigned to them for automatic renderer of data. This is particularly useful for numbers and dates where they can be automatically localised based on the user's browser settings and the detected data type, meaning you don't need to explicitly assign renderers yourself.
    • Event object passed to DataTables triggered events now has the DataTables API object available as the dt property for easy access to the API.
    • Full support for right-to-left languages for DataTables core out of the box.
    • Number renderer will display in scientific notation for numbers larger than 1e11 and less than 1e-5 (in keeping with how Excel and LibreOffice automatically format numbers)
    • Paging control is now responsive! It will automatically reduce the number of number buttons to fit the buttons into a single line in the container that they are placed in (i.e. this isn't just full page width responsiveness, but specifically based on the container for the paging buttons).
    • Paging plug-ins can now specify their own elements to be displayed, not just numbers and the five built in types. Fix: Pagination integration styling now supports the ability to set the string for a button to be an empty string. This can be useful if you want to show an icon for the button.
    • Support for border-collapse: collapse in the table styling.
    • Support for DOM nodes being resolved as the data points to be shown inside a DataTable (not just the return from a renderer for the display type).
    • column-selector now has a {string}:title option which can be used to select based on a column title
    • number option for the order option in selector-modifier which makes it possible to get the data from a column in the order DataTables would sort it in, regardless of the current sorting applied to the table.
    • Use colgroup and col elements for column width assignment. This is more accurate than assigning per header cell in complex headers where cells can span multiple columns.

Removed

  • Legacy API! fnAddData and friends were deprecated with the advent of DataTables 1.10 in 2014. It is now time for them to finally be removed.
  • Legacy sAjaxSource, fnServerData, sAjaxDataProp and fnServerParams.
  • Legacy server-side processing parameters. They are still available via the new legacy compatibility library and will automatically detect old configurations (e.g. sAjaxSource and DataTable.ext.legacy.ajax as before).
  • stripeClasses option which was used to set odd and even classes on the table rows. Instead use CSS's :nth-child() selector. The CSS option is far more performant, and while it wasn't a significant bottle neck in DataTables, removing this feature does release a surprising amount of code. If you really need odd and even classes on the rows you can use a row callback to add them.
  • concat() API method. It was totally broken, didn't do what it's documentation said it would, and therefore is unlikely to have been used. If you do have need for it, use .toArray() and then concat the resulting arrays.
  • deferLoading option. It is largely no longer relevant since search engines will execute Javascript and Ajax. It also required much more work if you were using renderers (since they would need to be implemented client and server-side) and caused issues with tables which required Ajax loaded options (such as SearchPanes).
  • The final vestiges of the legacy oApi property have now been removed. That object exposed the internal methods of DataTables. You should always use the public API.
  • F and H options for the original jQuery UI ThemeRoller integration in DataTables. To integrate with jQuery UI you should now use the jQuery UI integration files for DataTables, which was the preferred way for 1.10.
  • jQuery UI classes built into DataTables core. jQuery UI styling still supported via the integration file.
  • jQuery UI header renderer built into DataTables. Still supported via the jQuery UI integration, just like the other supported styling libraries.
  • Removing box sizing from CSS integration files

Deprecated

  • *.cache() methods. These have little utility with the *.render() methods being available and more flexible. Although they run the rendering calculation at the time of being called rather than reading from cache, they don't have invalidation issues and operate with all data types. The *.cache() methods will be removed in DataTables 3. In the unlikely event you are using these methods (they aren't used much!) it is recommended you update your code to use the *.render() methods.
  • dom option. The new layout option is much easier to use and works for all styling integrations. dom is widely used so it will remain in DataTables 2 and likely be removed from v3.

Updates

  • deferRender option is now default enabled
  • pagingType changed to be full_numbers causing the first and last buttons to be displayed in addition to the previous / next and numbers that were used before.
  • Modernise class names for DataTables controlled elements so they are more consistent, descriptive and readable. This can impact any customisation made via CSS or with selectors used on the DataTables defined classes. It is possible to revert to the DataTables 1.x class names - see the upgrade notes for details.
  • Change a tag to button for the pagination buttons (DataTables default styling). This is to help improve accessability. It has no visual impact as the CSS makes them look the same due to the applied class names.
  • Change language.lengthMenu default to be _MENU_ entries (was previously Show _MENU_ entries). This is done to improve accessability using an explicit link between the label and select.
  • DataTable.ext.classes property names and structure updated to be far more useful. This is unlikely to cause any issues unless you were setting any property values in this object to customise the class names DataTables uses for the table.
  • CSS file for DataTables changed from jquery.dataTables.css to dataTables.dataTables.css to match the structure of all the other files and extensions
  • In the download package move the js and css directories to the top level, rather than in a media directory. This brings DataTables core into sync with the extensions which have always had that structure. The media directory was a legacy from the early days!
  • Remove the background images used by DataTables for sorting icons on the header cells, replaced by UTF8 characters with suitable styling on pseudo elements to give the same effect
  • Stable / reset order - when applying an order, the table will now always do it from the initial load order (i.e. it resets back to that internally before performing the order). This is to address ordering on other columns and then returning back to the original ordering potentially resulting in a change in order.
  • Improve performance of column width calculations by caching longest string for each column
  • language.emptyTable will no longer fallback to language.zeroRecords if not defined. It is its own property and behaves like all the others now. It was introduced in 1.8 (2011) with the fallback as a stop gap.
  • JSON data examples now use ISO8601 for date information matching the DOM sourced data examples.
  • Making the auto column calculations more aggressive. The worst case table is now computed rather than using information from the DOM, as a simplification.
  • Order indication arrows are now inside a span to allow greater flexibility
  • Remove legacy IE hacks.
  • Remove TableTools styling from jQuery UI integration (TableTools is legacy and no longer supported)
  • Renaming the error event that DataTables triggered to be called dt-error. This is done to prevent the event triggering window.onerror functions with spurious information. That event should log script errors.
  • Rewriting how the column alignment for scrolling operates to be faster, more accurate and smaller.
  • Rewriting pagination plugin structure to move a lot of the logic from the plug-in to DataTables core, allowing the plugins to focus just on the DOM structure (elements, classes, etc). This also ensures consistent operation of the paging control across integrations, while still being fully styled by their styling frameworks. This has involved the addition of pagingButton and pagingContainer renderers for use by styling frameworks.
  • Search and length controls now use an explicit link for the label / input if possible. This is done to improve accessability as some screen readers struggle with the implicit link of having the input nested in the label. Note that our "macros" for the language strings make it possible to have the input in the middle of a text string - this is still supported and will use the original implicit nesting, but also with an explicit for/id. This however is not recommended and you should attempt to have the input at the start or end of the string to allow the label and input to not be nested.
  • Simplify the default pagination DOM by removing the span that wrapped the numbers in the pagination control.
  • Updates: Remove exposure of internal methods. This added 2KiB to the library, and the internal methods shouldn't be used internally. If you were using any, please update your code to use the public API.
  • Update - style: Make the table header and footer borders less harsh
  • Tailwind integration for DataTables 2 layout renderer
  • Use CSS borders to create the arrows for child row control rather than UTF-8 icons. Consistency between fonts was a problem.
  • When ordering is triggered by the build in event listener, it will no longer trigger a full search on the data in the table. This effectively decouples search and ordering from each other.

  • Better alignment for grid layout for styling libraries - now consistent with DT default

  • Better FomanticUI styling for narrow widths
  • Bootstrap 5 dark mode - control icons were not styled using the Bootstrap dark mode selector
  • Bulma styling should have a gap between rows
  • Check state age before triggering stateLoadParams
  • Colour between selected rows should use CSS variables
  • Column misalignment when scrolling with Foundation and some other styling frameworks
  • CommonJS loader, when there is a window did not define a module.exports property, resulting in errors when using this loader.
  • Correct inconsistency between thead cell borders in dark mode and light mode.
  • DataTables now uses a sparse array internally. This is only of significance when you delete rows with row().remove() (or the plural). Previously the indexes of all rows after the deleted row would be changed. That is no longer the case. The upshot is that the row indexes will always refer to the selected row, even if other rows were deleted.
  • Disable tab index on columns which are not orderable
  • Disable white background on table in BS5 and make it transparent
  • Disallow stackable view for table with FomanticUI styling. It causes issues with extensions such as FixedHeader and Scroller.
  • Disallow the footgun of setting displayStart if paging is disabled
  • Don't adjust column sizing on column visibility write if there was no change in column visibility.
  • Don't cache the reinsert point of the table on destroy. Compute it when the destroy is called (in case the container has been moved).
  • Don't check colspan of child rows for non-auto generated rows
  • Don't convert user input column sizes into pixels (i.e. allow column width calculations to be run on the input value, regardless of its unit).
  • ESLint detected errors.
  • column-visibility should only be fired on columns whose visibility changes.
  • Event listeners didn't include the selector second parameter option
  • requestChild was not being called when a state was loaded with child rows present
  • FomanticUI wasn't including table in the class list
  • Foundation styling for pagination shouldn't wrap disabled buttons with a tags
  • HTML read information had initial white space stripped before ordering, but not after the HTML tags were stripped, resulting in potentially incorrect sort results.
  • Improved margins for Bootstrap grid layout
  • Improvement for when browser zoom is enabled and scrolling
  • Improvements for Bootstrap 5 with table-bordered
  • Initial column sizing wasn't taking into account column header classes (sorting adds padding for example).
  • Initialising DataTables with no columns defined in HTML or the Javascript initialisation will no longer cause an error
  • initComplete never triggers if ajax.reload() is immediately called when an Ajax table is initialised.
  • order selector-modifier was ignored if items to select were being passed in as an array (e.g. table.rows([0, 2])). Correct ordering is now applied to the selected rows.
  • Pass only 3 parameters to order. Documentation has only ever had 3. The fourth was used internally originally but no longer is.
  • Performance optimisations for API instance creation
  • Per the documentation the order event should fire before a draw event. This brings into line with the search event and improves separation of concerns.
  • Plural methods were available on singular API invocations. For example row().nodes() was available, even although there was no definition for it - it was rows().nodes() leaking through.
  • Remove array compatibility methods for legacy browsers.
  • Remove blur from click events, allowing focus to remain on the selected element. Browser's no longer show a focus ring on click which is why this was originally there.
  • Remove !important where not required
  • Remove inline valign from the empty table cell and move to PHP Dev: Improve SCSS for typography
  • Remove jQuery from the dev repo - we don't need it here Update: Rename main JS file to dataTables.* rather than jquery.dataTables.*.
  • Remove jQuery.map usage - replace with Array.prototype.map or other suitable method
  • Remove polyfills for methods that are already in browsers that DT2 will support
  • Remove straggling $.isArray calls for jQuery 4 compatibility
  • Remove the use of $.merge from DataTables core
  • Remove zoom hack used for IE6
  • Row selected colouring was incorrectly being applied to even rows when not selected (incorrect CSS variable used)
  • Tabbing to focus on cells in the header with scrollX enabled could result in the header, body and footer misaligned due to the header scrolling, but not the other two.
  • Tailwind integration for DataTables 2
  • Typography classes weren't being applied in Fomantic UI
  • When destroying a table, if a resize event happens, don't attempt to resize the table.
  • When scrollY is enabled but scrollX is not and the container was too narrow for the table, the header and body would misalign when scrolled.

Typescript

  • cells() selector was not correct for the row + column overload
  • AjaxSettings wasn't being exported
  • column() and columns() were not correctly extending the API object Dev:
  • this is now an HTMLElement in event handlers
  • Typescript typings for DataTable.Api.register() did not set scope. They do now.
  • Define DataTablesStaticExtButtons interface which is completed by Buttons, to avoid conflicting types

Documentation

  • Documentation for the new feature controls and their options
  • Improve documentation for state duration in stateSave
  • Clarify use of defaultContent and render when used together
  • The page event is not called when the end user triggers a page length change. Instead length is triggered.
  • Was missing documentation for DataTable.datetime() static method.
  • Updating the examples to make use of the global DataTable variable rather than jQuery (although that will still work perfectly well and is fully supported). This reflects a more modern style.
  • Formatting of the example is now consistent

Examples

  • Ability to run the examples with any styling framework! This is done with a menu at the top left of the examples letting you select the styling framework to use for the example (matching how the initialisation code style and colour scheme can already be chosen). Some examples can still force a specific styling framework (e.g. the Bootstrap5 specific style).
  • A new set of examples that explicitly show the use of the new layout option.
  • Range filtering now uses a fixed filtering function
  • Show no sort option in orderSequence example
  • Row group example didn't have dark colours
  • Change class name for tabs under the table to stop conflict with styling integrations
  • Stop white flicker between pages when in dark mode
  • Update stripe url for the flags example
  • Foundation variant of form inputs example had margin under input elements
  • Update Material example to use 14.0.0
  • PHPStan highlighted errors in demo PHP server-side processing script

Files

js

css