Search code examples
jquerytablesorter

How to sort date with jquery tablesorter which is in format 'dd/mm/yyyy - dd/mm/yyyy'


I am having date in dd/mm/yyyy - dd/mm/yyyy format. How to sort this with jquery tablesorter. I try to sort it with sorter:"shortDate" and dateFormat:'ddmmyyyy' but it doesn't sort it in correct order.

<table>
<thead> 
    <tr><th>Date</th></tr>
</thead> 
<tbody>
<tr class="reportcell  odd ">
    <td>
        <div class="time">28/04/2014 - 11/07/2014</div>
    </td>
</tr>
<tr>
    <td>
        <div class="time">28/04/2014 - 13/05/2014</div>
    </td>
</tr>
<tr>
    <td>
        <div class="time">22/07/2014 - 22/07/2014</div>
    </td>
</tr>
<tr>
    <td>
        <div class="time">22/05/2014 - 22/05/2014</div>
    </td>
</tr>
</tbody>


Solution

  • You'll need to make a custom parser to be able to sort a column. There is an issue with this parser as it would be difficult to make it work properly with the filter widget (demo):

    $(function() {
    
        $.tablesorter.addParser({
            id: "date-range",
            is: function(){
                return false;
            },
            format: function(s, table, cell) {
                var dates = s.replace(/(\d{1,2})[\/\s](\d{1,2})[\/\s](\d{4})/g, "$2/$1/$3").split(' - '),
                    parsed = [];
                if (dates.length) {
                    $.each(dates, function(i,d){
                        var v = new Date(d);
                        parsed.push($.type(v) === 'date' ? v.getTime() : d);
                    });
                }
                return parsed.length ? parsed.join('') : s;
            },
            parsed : true,
            type: "text"
        });
    
        // call the tablesorter plugin
        $("table").tablesorter({
            headers : {
                0 : { sorter: 'date-range' }
            }
        });
    
    });
    

    Update (question from comments):

    The format function code does the following:

    • Modifiy the date by changing it from "dd/mm/yyyy" to "mm/dd/yyyy" so the date parser (new Date() will recognize the desired date setting)
    • The split(' - ') breaks apart the date range and creates two dates in an array from the range string.
    • dates.length makes sure we have an array with content
    • $.each() cycles through each date string
      • It creates a data object from the string
      • Then adds it to a new array as either a date in milliseconds or the original string if it isn't a valid date
    • It the returns the new array joined together (time in milliseconds of both dates) or the original string if there wasn't a date range.

    So, the reason why this method won't work with the filter widget is because the dates are combined (as a string, not added) to allow proper sorting of the parsed date. Also, from writing this description out I realize that a cell with a single date will not get parsed into a time in milliseconds, but instead be returned as the original date string. Either way non-date range cells will sort separate from the date range cells.