Using Jquery TableSorter, I am creating a custom parser to sort elapsed time <td>s that contain “‘#’ year(s) * ‘#’ month(s)”. When I use the function
$('.techtable td:nth-child(6)').each(function(){
// console.log($(this));
var that = $(this).text();
var myRegexp = /([\d]+) ([\w]+)(?: ([\d]+) ([\w]+))?/;
var match = myRegexp.exec($(this).text());
console.log(match);
});
from the command line, each index contains an array of length 5, looking like this:
["7 months", "7", "months", undefined, undefined]
to this:
["3 years 3 months", "3", "years", "3", "months"]
depending on whether or not the elapsed time has just a month or year element, and then the other. To parse the text, I use regex to gather each element, and then use JS to test whether there are multiple elements or not, and if 1 element only, then wheher it begins with “y” or “m”, and return the number of months, so the parser can sort the <td>s by number of months in integer form.
The parser passes in each element into the function as parameter “s”. when i try regex on “s” directly, it is not returning an array of length 5, it is truncating it to 3 (whether or not I am running the line that truncates it if index 3 is typeof ‘undefined’). When I use the console to directly use this function:
$('.techtable td:nth-child(6)').each(function(){
// console.log($(this));
var that = $(this).text();
var myRegexp = /([\d]+) ([\w]+)(?: ([\d]+) ([\w]+))?/;
var match = myRegexp.exec($(this).text());
if (typeof match[3] == 'undefined') {match.length = 3;};
console.log(match);
});
the regex returns the arrays properly, with the array truncated if it only has 1 element (year or month). Here is the code for the custom parser:
var myRegexp = /([\d]+) ([\w]+)(?: ([\d]+) ([\w]+))?/;
var match = myRegexp.exec(s);
var order = [];
console.log(match);
if (typeof match[3] == 'undefined') {match.length = 3;};
// 1 element case:
// month
if (match.length = 3) {
if (match[2][0] == "m") {
order.push(match[1]);
}
// year
if (match[2][0] == "y") {
order.push(match[1]*12);
}
// both elements
} else {
order.push(match[1]*12 + match[3]);
}
s = order;
return s;
},
The fiddle is here. The Elapsed parser is second from the bottom of the JS panel. As you can see, since I can’t get the months from the array (indices 4 and 5), I can not calculate the months, and thus the sorting only incorporates years, and the months are sorted by their original HTML placement. What am I missing? (I’m learning…. so direction is appreciated more than an fix, but I won’t turn it down.)
Yes I realize the JS fiddle is loaded (first part is TableSorter, to maintain functionality for verification(click on headers to sort), but all you need to focus on is the last part of the code (reference the ‘//Table Sorter dateSorter’ to see how a correct parser should look). The section ‘//Table Sorter elapsedSorter’ is where my two attempts are, the first part is the working code I use in the console, and the seconde part is the parser, which is somehow deleting the last two indices in the array, thus loosing the month information to calculate.
Guess I’ll have to add Regex, and a personal rating of 1, since I’ve wasted almost an entire day on this.
You meant this?
To help you further, when you write conditions with one constant and a variable, you can write them like this instead:
This would now cause a JavaScript error instead of silently getting turned into an assignment that always yields true.
In JavaScript,
12 + '4' == '124', so you have to be careful with numbers and the+operator. In languages such as PHP you don’t have this problem, because they have an operator for string concatenations 😉Btw use
parseInt(x, 10)if you expect fields to have leading zeroes (which would otherwise result in0being returned). Thanks fudgey!