5

I need to adapt the jQuery Tablesorter plugin to sort dates in a very simple format which will consist of the three letter month and the 4 digit date (e.g. May 2010, Jan 2011, Mar 2012, etc).

I have'nt been able to wrap my head around how to do it. I tried adapting the parser found here: http://beausmith.com/blog/custom-date-sorting-for-jquery-tablesorter-plugin/. But I am lost with reg ex. For ease in helping, I will post his code below.

// TableSort parser for date format: Jan 6, 1978
$.tablesorter.addParser({
id: 'monthDayYear',
is: function(s) {
  return false;
},
format: function(s) {
  var date = s.match(/^(\w{3})[ ](\d{1,2}),[ ](\d{4})$/);
  var m = monthNames[date[1]];
  var d = String(date[2]);
  if (d.length == 1) {d = "0" + d;}
  var y = date[3];
  return '' + y + m + d;
 },
type: 'numeric'
});
var monthNames = {};
monthNames["Jan"] = "01";
monthNames["Feb"] = "02";
monthNames["Mar"] = "03";
monthNames["Apr"] = "04";
monthNames["May"] = "05";
monthNames["Jun"] = "06";
monthNames["Jul"] = "07";
monthNames["Aug"] = "08";
monthNames["Sep"] = "09";
monthNames["Oct"] = "10";
monthNames["Nov"] = "11";
monthNames["Dec"] = "12";

Any ideas on how to just format it for month names and year? Thanks!

UPDATE: I have tried to implement some code both from Sam and Fudgey below (thank you for being so helpful thus far!). I can't quite get it to work. I tried to use fugey's code sample because I see where it is working exactly as needed on the fiddle demo. Below is my HTML markup:

<table id="myTable" class="stripeMe sample" width="100%" cellpadding="0"    cellspacing="0">
<thead>
<th width="30%" align="left">COMPANY</th><th width="35%">DESCRIPTION</th><th width="17%"   align="left">INDUSTRY</th><th width="18%" align="left">EXIT DATE</th></tr></thead>
<tbody>
<tr><td width="30%">   <a href="http://www.cartera.com/vesdia.html "> Cartera Commerce,  Inc.</a>  </td>
<td width="35%">Provides technology-enabled marketing and loyalty solutions 
</td><td width="17%">   Financials  </td><td width="18%">Feb 2010</td></tr><tr><td  width="30%">   <a href="http://www.criticalinfonet.com/ "> Critical Information Network,   LLC</a>  </td>
<td width="35%">Operates library of industrial professional training and certification   materials 
</td><td width="17%">   Education  </td><td width="18%">Apr 2011</td></tr><tr><td     width="30%">   <a href="http://www.cynergydata.com/ "> Cynergydata</a>  </td>
<td width="35%">Provides merchant payment processing services and related software products 
</td><td width="17%">   Merchant Processing  </td><td width="18%">May 2011</td></tr><tr>  <td width="30%">   <a href=" "> EVCI Career Colleges Holding Corp</a>  </td>
<td width="35%">Operates post-secondary schools  
</td><td width="17%">   Education  </td><td width="18%">Jul 2012</td></tr><tr><td  width="30%">   <a href="http://www.groundlink.com/ "> Groundlink, Inc.</a>  </td>
<td width="35%">Provides ground transportation services domestically and internationally 
</td><td width="17%">   Transportation  </td><td width="18%">Feb 2012</td></tr><tr><td  width="30%">   <a href="http://www.haggen.com/ "> Haggen, Inc.</a>  </td>
<td width="35%">Operates chain of high-end grocery stores in the Pacific Northwest 
</td><td width="17%">   Grocery  </td><td width="18%">Aug 2011 </td></tr>

</tbody>
</table>

And then the script I am using, which is fudgey's but I changed the column header number to 3 (it's the 4th column in my table) and I changed the call to the tablesorter to use the id of the table, which in this case is the ever original #myTable. I also wrapped it in jQuery's $(document).ready:

$(document).ready(function() { 
$.tablesorter.addParser({
id: 'monthYear',
is: function(s) {
return false;
},
format: function(s) {
var date = s.match(/^(\w{3})[ ](\d{4})$/);
var m = date ? date[1] + ' 1 ' || '' : '';
var y = date && date[2] ? date[2] || '' : '';
return new Date(m + y).getTime() || '';
},
type: 'Numeric'
});

$('#myTable').tablesorter({
headers: {
    3: {
        sorter: 'monthYear'
    }
}
});
});

And it is still not sorting that column by date, I'm not sure how it is sorting it - I get a sort in this order, which almost seems right but look at where that Feb 2010 falls, right in the middle of 2011 dates - weird: Aug 2011 Feb 2010 Apr 2011 May 2011 Feb 2012 Jul 2012

seanx
  • 131
  • 3
  • 11
  • Anyone have any ideas? Thanks! – seanx May 06 '12 at 16:05
  • You need to return the date in milliseconds, and no need for the monthNames array. [See my answer to this question](http://stackoverflow.com/questions/9568473/sort-date-field-with-tablesorter/9572850#9572850). – Vik David May 07 '12 at 18:44
  • Thank you for answering Vik - however, when I add your code, I get the following error:TypeError: 'function parse() { [native code] }' is not a constructor (evaluating 'new Date.parse(s)') – seanx May 09 '12 at 18:01

2 Answers2

2

With well-formed dates, this should be your answer:

$.tablesorter.addParser({
    id: 'monthYear',
    is: function(s) {
        return false;
    },
    format: function(s) {
        var date = s.match(/^(\w{3})[ ](\d{4})$/);
        var m = date[1];
        var y = date[2];
        return new Date(m + ' ' + 1 + ' ' + y);
    },
    type: 'date'
});

$(document).ready(function() {
    $('.tablesorter').tablesorter({
      headers: {
         1: {
            sorter: 'monthYear'
         }
      }
   });
});

It uses a regex to extract the month abbreviation and the year, then converts them into a date for sorting.

Sam Tyson
  • 4,496
  • 4
  • 26
  • 34
  • Thanks for taking the time to answer Sam, I understand the general principle on what you have posted here, but I get the following error:TypeError: 'null' is not an object (evaluating 'date[1]'). Any ideas on why? Thanks! – seanx May 09 '12 at 18:02
  • Coincidentally, when I go back in and try to original code I entered in my original question, I get the same error – seanx May 09 '12 at 18:03
  • It sounds like your data is not formatted as the regex expects it to be. Can you post some of the date column? – Sam Tyson May 09 '12 at 21:15
  • Thanks Sam, I posted some code above, I was using fudgey's code from below which builds on your own. It still will not sort that column by date, it's doing it alphabetically. – seanx May 10 '12 at 15:23
  • Thank you again Sam, I am getting it working now, I had to remove some spaces in the table cell. – seanx May 10 '12 at 19:33
2

I've modified @SamTyson's answer:

There are three things that changed:

  1. The format function needs to be able to handle empty table cells.
  2. The format function must return a string or number
  3. The parser type can only be "Numeric" or "Text".

So, I ended up with this parser code and this demo.

$.tablesorter.addParser({
    id: 'monthYear',
    is: function(s) {
        return false;
    },
    format: function(s) {
        // remove extra spacing
        s = $.trim(s.replace(/\s+/g, ' '));
        // process date
        var date = s.match(/^(\w{3})[ ](\d{4})$/),
            m = date ? date[1] + ' 1 ' || '' : '',
            y = date && date[2] ? date[2] || '' : '';
        return new Date(m + y).getTime() || '';
    },
    type: 'Numeric'
});

$('table').tablesorter({
    headers: {
        0: {
            sorter: 'monthYear'
        }
    }
});

Update: Added a line to trim out extra spaces.

Mottie
  • 84,355
  • 30
  • 126
  • 241
  • Thank you fudgey, that is indeed the formatting I need, and I see how your demo is working perfectly. I can't seem to get it to work in my table! I am reposting the code I am using above so that perhaps someone might spot something I am doing wrong. – seanx May 10 '12 at 15:14
  • Ok, update 2: I have figured out why it wasn't working - there are spaces on either side of the date text within the tags. My question then, is there a way to account for this in the parser? These seem to be inserted automatically, I am using WordPress and the Advance Custom Field plugin. This table will be edited by an end user admin, so I may have to also track down the reason spaces are being inserted by the plugin - but in the mean time, is there a way to check for spaces and ignore, or does it have to match exactly - thanks! – seanx May 10 '12 at 19:08
  • Update 3: I have it working - I was able to go into my template file and reformat HTML/php markup to make sure that no extra spaces were inserted into the table cell. One more question: The way this client wants their column, they want to include companies labeled 'Active' and then also have companies that have excited the group - the ones that have excited are the ones we have been sorting by the date, formatted above. I can place 'active' in the date column, and it lists either at the top or the bottom of the column once sorted - however, I am wishing that the chronological order of the – seanx May 10 '12 at 19:30
  • companies were reversed - I want the Active companies listed first, followed by the date sorted companies starting with the most recent and listing down to the oldest at the bottom of the list. Currently, it displays Active, then the date sorted companies with the oldest down to the most recent. Is there a relatively easy way to account for/change this? Thanks for your help so far, you have been a life saver – seanx May 10 '12 at 19:32
  • Ok, I added a line of code to remove extra spacing before trying to determine the date. Here is an [updated demo](http://jsfiddle.net/Mottie/vCTHw/116/) – Mottie May 11 '12 at 01:03
  • Is there any similar solution for this but including days in front? I have many empty fields for for lines that don't yet have a deadline. – Alisso Oct 23 '12 at 03:20