Search code examples
jquerysortingdatatablesemptydatatext

Sorting (alphabetical order) to ignore empty cells : dataTables


So the question has already been asked here, but the solution doesn't work for me (I might do something wrong). I want to sort my tables by alphabetical order ("type" : "natural"), but I want the empty cells to be at the bottom (for desc and asc).

I tried the previous solution given by fbas :

jQuery.fn.dataTableExt.oSort['mystring-asc'] = function(x,y) {
    var retVal;
    x = $.trim(x);
    y = $.trim(y);

    if (x==y) retVal= 0;
    else if (x == "" || x == " ") retVal=  1;
    else if (y == "" || y == " ") retVal=  -1;
    else if (x > y) retVal=  1;
    else retVal = -1;  // <- this was missing in version 1

    return retVal;
}
jQuery.fn.dataTableExt.oSort['mystring-desc'] = function(y,x) {
    var retVal;
    x = $.trim(x);
    y = $.trim(y);

    if (x==y) retVal= 0; 
    else if (x == "" || x == "&nbsp;") retVal=  -1;
    else if (y == "" || y == "&nbsp;") retVal=  1;
    else if (x > y) retVal=  1;
    else retVal = -1; // <- this was missing in version 1

    return retVal;
 }

With :

$(document).ready(function() {
    $('#classement').dataTable({
    "aoColumns": [
        null,
        null,
        { "type" : "mystring" },
        { "type" : "mystring" },
        null
    ]
    } );
} );

With a table like | N° | Edit | Song | Singer | Url | Sorting only on Song and Singer.

The emty cells are at the bottom (as expected) but now the sorting has no logic (no alphabetical order, should I use another property in dataTable?).

Does anyone have a solution?

Edit : If we add a line dynamically, how to refresh the sorting ?

$("#example").find('tbody')
    .append($('<tr>')
        .append($('<td>')
                .text('Boro')
            )     
    );

JsFiddle (use isim's one)


Solution

  • UPDATE: Embedded Stack Snippet.

    I think the aoColumns is a legacy option for DataTables v 1.9. That being said, you might also need to use $.extend to include your custom sort functions.

    Please take a look at the Stack Snippet below, or this live demo on jsfiddle. In a nutshell, I define the name column as the type non-empty-string during the table initalization. Then I extended the jQuery.fn.dataTableExt.oSort API with a non-empty-string-asc and a non-empty-string-desc sorting functions. See if this is what you are looking for.

    Stack Snippet:

    jQuery.extend( jQuery.fn.dataTableExt.oSort, {
        "non-empty-string-asc": function (str1, str2) {
            if(str1 == "")
                return 1;
            if(str2 == "")
                return -1;
            return ((str1 < str2) ? -1 : ((str1 > str2) ? 1 : 0));
        },
     
        "non-empty-string-desc": function (str1, str2) {
            if(str1 == "")
                return 1;
            if(str2 == "")
                return -1;
            return ((str1 < str2) ? 1 : ((str1 > str2) ? -1 : 0));
        }
    } );
    
    
    var dataTable = $('#example').dataTable({
        columnDefs: [
           {type: 'non-empty-string', targets: 0} // define 'name' column as non-empty-string type
        ]
    });
    dataTable.api().row.add(['John Smith', 'Intern', 'San Francisco', 19, 2011/05/25, 62000]).draw();
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="http://cdn.datatables.net/1.10.2/js/jquery.dataTables.min.js"></script>
    <link href="http://cdn.datatables.net/1.10.2/css/jquery.dataTables.css" rel="stylesheet"/>
    
    <table id="example" class="display" cellspacing="0" width="100%">
        <thead>
            <tr>
                <th>Name</th>
                <th>Position</th>
                <th>Office</th>
                <th>Age</th>
                <th>Start date</th>
                <th>Salary</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>Tiger Nixon</td>
                <td>System Architect</td>
                <td>Edinburgh</td>
                <td>61</td>
                <td>2011/04/25</td>
                <td>$320,800</td>
            </tr>
            <tr>
                <td>Garrett Winters</td>
                <td>Accountant</td>
                <td>Tokyo</td>
                <td>63</td>
                <td>2011/07/25</td>
                <td>$170,750</td>
            </tr>
            <tr>
                <td>Ashton Cox</td>
                <td>Junior Technical Author</td>
                <td>San Francisco</td>
                <td>66</td>
                <td>2009/01/12</td>
                <td>$86,000</td>
            </tr>
            <tr>
                <td>Cedric Kelly</td>
                <td>Senior Javascript Developer</td>
                <td>Edinburgh</td>
                <td>22</td>
                <td>2012/03/29</td>
                <td>$433,060</td>
            </tr>
            
            <tr>
                <td></td>
                <td>Junior Technical Author</td>
                <td>San Francisco</td>
                <td>66</td>
                <td>2009/01/12</td>
                <td>$86,000</td>
            </tr>
            <tr>
                <td></td>
                <td>Senior Javascript Developer</td>
                <td>Edinburgh</td>
                <td>22</td>
                <td>2012/03/29</td>
                <td>$433,060</td>
            </tr>
            
        </tbody>
    </table>