JQuery DataTables - sorting doesn't work when date is also a link

I notice that sorting a date in the UK does not work when the date is also a reference.

Example 1. ( demo )

Here the date is a clean test. Works great.

<tr> <td>01/01/01</td> <td>Tarik</td> <td>Rashad Kidd</td> <td>1 34 238 6239-0509</td> </tr> 

Example 2. ( demo )

Here, the date is also a link. Doesn't work at all. Do not throw any mistakes.

  <tr> <td><a href="#">01/01/01</a></td> <td>Tarik</td> <td>Rashad Kidd</td> <td>1 34 238 6239-0509</td> </tr> 

I also noticed that sorting works with any other elements, even if they are a link. The problem is with the date as a reference.

I am using the following JS code:

 // UK Date Sorting jQuery.fn.dataTableExt.oSort['uk_date-asc'] = function(a,b) { var ukDatea = a.split('/'); var ukDateb = b.split('/'); var x = (ukDatea[2] + ukDatea[1] + ukDatea[0]) * 1; var y = (ukDateb[2] + ukDateb[1] + ukDateb[0]) * 1; return ((x < y) ? -1 : ((x > y) ? 1 : 0)); }; jQuery.fn.dataTableExt.oSort['uk_date-desc'] = function(a,b) { var ukDatea = a.split('/'); var ukDateb = b.split('/'); var x = (ukDatea[2] + ukDatea[1] + ukDatea[0]) * 1; var y = (ukDateb[2] + ukDateb[1] + ukDateb[0]) * 1; return ((x < y) ? 1 : ((x > y) ? -1 : 0)); } $(document).ready(function() { $('#table').dataTable( { "bPaginate": true, "bLengthChange": true, "bFilter": true, "aoColumnDefs" : [ { "aTargets" : ["uk-date-column"] , "sType" : "uk_date"} ] }); }); 

Any help is greatly appreciated.

+4
source share
4 answers

The problem is that the sort function gets confused with the extra html. You should change your functions as follows:

 // UK Date Sorting jQuery.fn.dataTableExt.oSort['uk_date-asc'] = function(a,b) { //use text() var ukDatea = $(a).text().split('/'); var ukDateb = $(b).text().split('/'); var x = (ukDatea[2] + ukDatea[1] + ukDatea[0]) * 1; var y = (ukDateb[2] + ukDateb[1] + ukDateb[0]) * 1; return ((x < y) ? -1 : ((x > y) ? 1 : 0)); }; jQuery.fn.dataTableExt.oSort['uk_date-desc'] = function(a,b) { //use text() var ukDatea = $(a).text().split('/'); var ukDateb = $(b).text().split('/'); var x = (ukDatea[2] + ukDatea[1] + ukDatea[0]) * 1; var y = (ukDateb[2] + ukDateb[1] + ukDateb[0]) * 1; return ((x < y) ? 1 : ((x > y) ? -1 : 0)); } 

fiddle here http://jsfiddle.net/GUb2n/

+4
source

You can try to put the date (in ISO format) in an invisible container before the link:

 <span style="display: none;">2001-01-01</span><a href="#">01/01/01</a> 

Then alphabetical sorting should work.

+3
source

IIRC, incorrect sorting of related data is related to the way DataTables tries to remove HTML from the contents of a table cell (using a simplified regular expression), which seems unable to completely extract date data from the cell.

Datasheets 1.10+ can use HTML 5 data attributes to avoid this problem.

If you have a link in the <td> tag set, for example:

 <td><a href = "someobject">28 July 2015</a></td> 

you can add the data-order attribute to the <td> :

 <td data-order="2015-07-28"><a href = "someobject">28 July 2015</a></td> 

This data-order attribute allows DataTables to sort by the data-order attribute and use the content between the <td> tags only as displayed data.

+1
source

(v1.9.4) This solution not only fixes your sorting problems, but also eliminates filtering problems, because the filter usually matches HTML, so searching for things like href or div matches all the lines.

It removes the HTML inside the mRender option, and then caches the result, since DataTables runs the mRender function several times.

JsFiddle example

Warning for editable tables

An editable table may have problems due to the caching mechanism.

Step1

Include the following javascript somewhere:

 var stripHtml = (function() { var tmpDiv = document.createElement("DIV"); return function(html) { tmpDiv.innerHTML = html; return $.trim(tmpDiv.textContent || tmpDiv.innerText); }; })(); var mRenderFactory = function (colIndex) { return function (data, type, full) { var cache = MRenderCache.getCache(full); if (type === "filter" || type === "sort" || type === "type") { return cache.getOrElse(colIndex, data, stripHtml) } return data; }; }; var MRenderCache = function () { this.full = []; } MRenderCache.getCache = function (full) { var cache = full[full.length - 1]; if (cache == null || !cache.MRenderCache) { cache = new MRenderCache(); full.push(cache); } return cache; } MRenderCache.prototype.MRenderCache = true; MRenderCache.prototype.getOrElse = function (colIndex, rawData, convert) { var result = this.full[colIndex]; if (result === undefined) { result = convert(rawData); this.full[colIndex] = result; } return result; } 

Step 2

Set "mRender": mRenderFactory(i) inside aoColumns in any columns that you want HTML to split, where i is the column index. It is VERY important that you get the correct i , because if you do not, the table will be displayed in order, but it will sort and filter the wrong column.

The initialization code will look something like this:

 $(document).ready(function() { $('#example').dataTable( { "aoColumns": [ null, null, { "mRender": mRenderFactory(2) }, { "mRender": mRenderFactory(3) }, null ] } ); } ); 
0
source

Source: https://habr.com/ru/post/1400199/


All Articles