Introduction

The Datatables library can add a great deal of functionality to plain HTML tables. I will focus on a couple of sorting and filtering techniques which I have found useful - and which build on some discussions here.

To keep things simple I will use static data.

Here is my demonstration table in its entirety:

And here is the code which produced it (I just placed this in a text file - demo.htm - and opened it with Firefox):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<!doctype html>  
<html lang="en">  
<head>  
  <meta charset="utf-8">  
  <title>Animals</title>  
  <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>  
  <script src="https://cdn.datatables.net/1.10.20/js/jquery.dataTables.min.js"></script>  
  <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.20/css/jquery.dataTables.min.css">  
  <link rel="stylesheet" type="text/css" href="https://datatables.net/media/css/site-examples.css">  
</head>  

<body>  

<div style="margin: 20px;">  

<table id="animals" class="display dataTable cell-border" style="width:100%">  
  <thead>  
   <tr><th>Animal</th><th>Collective Noun</th><th>Language</th></tr>  
  </thead>  
  <tbody>  
    <tr><td>antelopes</td><td>herd</td><td>English</td></tr>  
    <tr><td>cats</td><td>clowder</td><td>English</td></tr>  
    <tr><td>éléphants</td><td>troupeau</td><td>French</td></tr>  
    <tr><td>Hounds</td><td>pack</td><td>English</td></tr>  
    <tr><td>kittens</td><td>kindle</td><td>English</td></tr>  
    <tr><td>lions</td><td>pride</td><td>English</td></tr>  
    <tr><td>pingouins</td><td>colonie</td><td>French</td></tr>  
    <tr><td> ravens</td><td>unkindness</td><td>English</td></tr>  
    <tr><td>whales</td><td>pod</td><td>English</td></tr>  
    <tr><td>zebras</td><td>herd</td><td>English</td></tr>  
  </tbody>  
</table>  

</div>  

<script type="text/javascript">  
  $(document).ready(function() {  
      $('#animals').DataTable();  
  });  
</script>  

</body>

By default the data is sorted on the first column.

Better Sorting

You can see that upper and lower case words are handled correctly (Hounds is listed before kittens).  And the extra leading space in front of ravens is removed. But the accented word éléphant has been relegated to the bottom of the list.

To fix the ordering we need to add a language collation to DataTables:

1
2
3
4
$.fn.dataTable.ext.order.intl('en');  
$(document).ready(function() {  
    $('#animals').DataTable();  
});  

That first line uses a DataTables plugin based on JavaScript’s intl API. Because it’s a plugin, I also need to add this to the HTML header:

1
<script src="https://cdn.datatables.net/plug-ins/1.10.20/sorting/intl.js"></script>

Now my sort order looks good:

The collation I’m using is for English (‘en’). That may or may not be what you need.

There are lots of plugins for DataTables - have a browse.

Better Filtering

To illustrate the next problem, I will first make a small change to the data, by replacing my clowder of cats with an English herd of elephants:

Now I can find either French elephants:

Or English elephants:

But I have to get creative if I want to find all elephants:

To fix this, we have to do a number of things - as discussed here.

  1. Add a hidden - but searchable - column to my DataTable, and populate it with data to support better filtering.

  2. Intercept the filter term entered by the user, and strip out any accents (diacritics) before applying the filter.

Here is what the code looks like after making those changes:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
<!doctype html>  
<html lang="en">  
<head>  
  <meta charset="utf-8">  
  <title>Animals</title>  
  <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>  
  <script src="https://cdn.datatables.net/1.10.20/js/jquery.dataTables.min.js"></script>  
  <script src="https://cdn.datatables.net/plug-ins/1.10.20/sorting/intl.js"></script>  
  <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.20/css/jquery.dataTables.min.css">  
  <link rel="stylesheet" type="text/css" href="https://datatables.net/media/css/site-examples.css">  
</head>  

<body>  

<div style="margin: 20px;">  

<table id="animals" class="display dataTable cell-border" style="width:100%">  
  <thead>  
   <tr><th>Animal</th><th>Collective Noun</th><th>Language</th><th>hiddenFilterData</th></tr>  
  </thead>  
  <tbody>  
    <tr><td>antelopes</td><td>herd</td><td>English</td><td></td></tr>  
    <tr><td>elephants</td><td>herd</td><td>English</td><td></td></tr>  
    <tr><td>éléphants</td><td>troupeau</td><td>French</td><td>elephants</td></tr>  
    <tr><td>Hounds</td><td>pack</td><td>English</td><td></td><</tr>  
    <tr><td>kittens</td><td>kindle</td><td>English</td><td></td></tr>  
    <tr><td>lions</td><td>pride</td><td>English</td><td></td></tr>  
    <tr><td>pingouins</td><td>colonie</td><td>French</td><td></td></tr>  
    <tr><td> ravens</td><td>unkindness</td><td>English</td><td></td></tr>  
    <tr><td>whales</td><td>pod</td><td>English</td><td></td></tr>  
    <tr><td>zebras</td><td>herd</td><td>English</td><td></td></tr>  
  </tbody>  
</table>  

</div>  

<script type="text/javascript">  

  $.fn.dataTable.ext.order.intl('en');  

  $(document).ready(function() {  
    var table = $('#animals').DataTable({  
      "columnDefs": [  
        {  
          "visible": false,  
          "targets": [-1]  
        }  
      ]  
    });  

    $('#animals_filter input').off().keyup(function (e) {  
      var newval = this.value.normalize("NFD")  
          .replace(/[\u0300-\u036f]/g, "");  
      table.search(newval).draw();  
    });  

  });  
</script>  

</body>

We can now find all our elephants:

What changes did we make?

  1. In the body of the table (lines 22-31) we added an extra column.  We populated that column with any data where accents needed to be stripped from data in the rest of the row. In the Real World, this extra data would probably come from the data source (our server), along with the standard data set we are displaying.

  2. We specified our new column  as “hidden” - lines 45-46.  The “-1” means “the last column in the table”. A “-2” would mean “second to last”, and so on.

  3. In the JavaScript at line 42, we assigned our DataTable to a variable, so that we could reference it later.

  4. We added a keyup event handler (line 51) for the filter box.  The event handler removed accents from the search term (as discussed here), before applying the search.

  5. Note that the event handler includes the DataTables off() function, to remove the default keyhandler event.  Without this, filtering - and the table re-draw - will happen twice.

That’s a somewhat contrived example, but the technique is directly applicable to the Real World, and gives us a much more user-friendly approach to sorting and filtering.

DataTables makes it all straightforward, too.