Soatl
Soatl

Reputation: 10592

jQuery Datatables: Sort on one column when clicking on another.

I have a jQuery datatable with date and time columns:

Date        Time        Note
1/2/2015    10:02:03    Test
1/4/2915    02:12:32    Test
1/3/2015    02:05:03    Test
3/2/2015    11:02:03    Test
1/4/2015    01:02:13    Test

I want to implement a sort for time. When sorting on time, we first need to sort on date, then time:

Date        Time        Note
1/2/2015    10:02:03    Test
1/3/2015    02:05:03    Test
1/4/2015    01:02:13    Test
1/4/2915    02:12:32    Test
3/2/2015    11:02:03    Test

I have the following code:

//jQuery datatable code
{ mData: 'date', sTitle: 'Date', sClass: "dtDate" },
{ mData: 'time', sTitle: 'Time', sClass: "dtTime", sType: "time-date-sort"},
{ mData: 'notes', sTitle: 'Notes' },
// More code...

jQuery.fn.dataTableExt.oSort['time-date-sort-asc'] = function(startTime, endTime) {      
    //Date and time sorts go here
    return sortedVal;
};

jQuery.fn.dataTableExt.oSort['time-date-sort-desc'] = function (startTime, endTime) {
    //Date and time sorts go here
    return sortedVal;
};

I am able to sort on the time using this, but how would I first sort on date? I am trying to figure out how to get a reference of the date value in the table row (associated with the time value in that row). For example, how to I grab the date object 1/2/2015 for the row where time is 10:02:03? It does not appear as if I can add custom parameters to the oSort function. Do I use jQuery.fn.dataTableExt.oSort or is jQuery.fn.dataTableExt.afnSortData a better option for this?

Upvotes: 1

Views: 2749

Answers (1)

davidkonrad
davidkonrad

Reputation: 85528

To get values from other columns to be included in your custom sort you must create a custom data source sorting plug-in. The below will return the values from column 0 and 1 as a date+time string, ie 1/2/2015 10:02:03 :

$.fn.dataTable.ext.order['order-time-date-sort'] = function(settings, col) {
    return this.api().row({order:'index'} ).nodes().map(function (tr, i) {
        return $('td:eq(0)', tr).text()+' '+$('td:eq(1)', tr).text();
    });    
}

Then set the above order-date-time-sort as orderDateType for the time column :

var table = $('#example').DataTable({
    columnDefs : [
        { type: 'time-date-sort', 
          orderDataType: "order-time-date-sort", 
          targets: [1] 
        }
    ]                                     
});

Now the time can be sorted with respect of the date too, using simple Date.parse() :

jQuery.fn.dataTableExt.oSort['time-date-sort-pre'] = function(value) {      
    return Date.parse(value);
};
jQuery.fn.dataTableExt.oSort['time-date-sort-asc'] = function(a,b) {      
    return a-b;
};
jQuery.fn.dataTableExt.oSort['time-date-sort-desc'] = function(a,b) {
    return b-a;
};

demo -> http://jsfiddle.net/4toLj9yn/


Note: If you have problems with performance, it could happend with a huge table, you should "cache" the result of order-time-date-sort (simply store the result in a variable). You could also consider using a completely diffrent approach - orthogonal data.

Upvotes: 1

Related Questions