Sorting stops working when you include HTML?

Sorting stops working when you include HTML?

soapergemsoapergem Posts: 3Questions: 1Answers: 0

This is a bug report -- I noticed that sorting does not work correctly when you add in HTML to the end of the cells. I wouldn't think this would impact cells where they start with numerical values, but apparently it does.

Example where sorting works: http://jsfiddle.net/phb9Lms6/

Example where sorting does NOT work: http://jsfiddle.net/phb9Lms6/1/

Click on the "Totals" column to see what I mean. How do I fix this?

Answers

  • allanallan Posts: 61,726Questions: 1Answers: 10,109 Site admin

    DataTables strips the HTML and then sorts what remains. However in this case:

    <td><span style="display:none;">02</span>February</td

    Strip the HTML and you get:

    02February

    That is a string and can't be sorted numerically.

    If you want to sort numerically with string data shown, use HTML5 data-* attributes.

    Allan

  • soapergemsoapergem Posts: 3Questions: 1Answers: 0

    Allan, thanks for your reply. However, the first column with the months is NOT what this issue is about. That one's fine. Look at the second column please -- the one called "Totals." (I specified that in the OP.)

  • john_ljohn_l Posts: 45Questions: 0Answers: 12

    It looks like the HTML you have added in the cell to indicate the 'Current' total is causing Datatables to use a different sorting function for that column - one which takes the first number found - which for many of the rows turns out to be just '1' - as it gets cut off by the ',' thousand separator.

    The solution is as Allan suggested - put the real number you want to sort on into an attribute (without and extra formatting), and sort based on that. In the past I've used the 'ref' attribute, and added sort extension functions to work on that, but it looks like 1.10 now has built in functionality for this.

  • soapergemsoapergem Posts: 3Questions: 1Answers: 0

    Thanks John. In reality I don't have a hard-coded HTML table as my data source; I'm actually pulling data from an AJAX endpoint. Then I've got the columns defined like this in the table options:

    [{data: "column1", render: function() {...}}, {data: "column2", render: ...}, ...]
    

    Then my render function is what is actually adding the "current" HTML in some cases. How would I specify extra attributes for these columns using this style? Or how could I force a sorting algorithm this way? While still not using AJAX, the following link is perhaps a better illustration of my use case (look around line 38 of the JS):

    http://jsfiddle.net/phb9Lms6/5/

  • john_ljohn_l Posts: 45Questions: 0Answers: 12

    What I've done in the past is to wrap the column data in a span, and add the attributes onto the span, when generating the ajax data on the server, so a particular cells data might look like this:

    "<span class='indicatorRed' ref='1'>High</span>"

    (This also let me use the class on the span to specially format the cell with CSS that wouldn't work on the 'td'.)
    I'd have this column specified with an sType of 'ref-numeric', and add that as a new sort extension:

    $.fn.dataTableExt.oSort['ref-numeric-asc'] = function (a, b) {
        var x = a ? a.match(/ref=['"]*(-?[0-9\.]+)/)[1] : "0";
        var y = b ? b.match(/ref=['"]*(-?[0-9\.]+)/)[1] : "0";
        x = parseFloat(x);
        y = parseFloat(y);
        return ((x < y) ? -1 : ((x > y) ? 1 : 0));
    };
    
    $.fn.dataTableExt.oSort['ref-numeric-desc'] = function (a, b) {
        var x = a ? a.match(/ref=['"]*(-?[0-9\.]+)/)[1] : "0";
        var y = b ? b.match(/ref=['"]*(-?[0-9\.]+)/)[1] : "0";
        x = parseFloat(x);
        y = parseFloat(y);
        return ((x < y) ? 1 : ((x > y) ? -1 : 0));
    };
    
  • allanallan Posts: 61,726Questions: 1Answers: 10,109 Site admin

    @soapergem - Sorry I used the wrong column, however as @john_l says the same point stands since it is still being detected as a string.

    The best way to handle it is to still use orthogonal data. You wouldn't use data attributes if you are Ajax loading the data, you would use the parameters directly. Have a read through the orthogonal manual page I linked to before (rather than just the HTML5 specific bit).

    There is also an example that you might find useful.

    Allan

This discussion has been closed.