3 -----------------------
\r
5 This function sorts English dateTime vaues such as:
\r
7 1st January 2003, 23:32:01
\r
8 23/03/1972 à 10:22:22
\r
9 1970/13/03 at 23:22:01
\r
11 The function is "safe" i.e. non-dateTime data (like the word "Unknown") can be passed in and is sorted properly.
\r
13 var sortEnglishDateTime = fdTableSort.sortNumeric;
\r
15 function sortEnglishDateTimePrepareData(tdNode, innerText) {
\r
16 // You can localise the function here
\r
17 var months = ['january','february','march','april','may','june','july','august','september','october','november','december','jan','feb','mar','apr','may','jun','jul','aug','sep','oct','nov','dec'];
\r
19 // Lowercase the text
\r
20 var aa = innerText.toLowerCase();
\r
22 // Replace the longhand months with an integer equivalent
\r
23 for(var i = 0; i < months.length; i++) {
\r
24 aa = aa.replace(months[i], (i+13)%12);
\r
27 // Replace multiple spaces and anything that is not valid in the parsing of the date, then trim
\r
28 aa = aa.replace(/\s+/g, " ").replace(/([^\d\s\/-:.])/g, "").replace(/^\s\s*/, '').replace(/\s\s*$/, '');
\r
30 // No timestamp at the end, then return -1
\r
31 if(aa.search(/(\d){2}:(\d){2}(:(\d){2})?$/) == -1) { return -1; };
\r
33 // Grab the timestamp
\r
34 var timestamp = aa.match(/(\d){2}:(\d){2}(:(\d){2})?$/)[0].replace(/:/g, "");
\r
36 // Make the timestamp 6 characters by default
\r
37 if(timestamp.length == 4) { timestamp += "00"; };
\r
39 // Remove it from the string to assist the date parser, then trim
\r
40 aa = aa.replace(/(\d){2}:(\d){2}(:(\d){2})?$/, "").replace(/\s\s*$/, '');
\r
42 // If you want the parser to favour the parsing of European dd/mm/yyyy dates then leave this set to "true"
\r
43 // If you want the parser to favour the parsing of American mm/dd/yyyy dates then set to "false"
\r
44 var favourDMY = true;
\r
46 // If you have a regular expression you wish to add, add the Object to the end of the array
\r
48 { regExp:/^(0?[1-9]|1[012])([- \/.])(0?[1-9]|[12][0-9]|3[01])([- \/.])((\d\d)?\d\d)$/, d:3, m:1, y:5 }, // mdy
\r
49 { regExp:/^(0?[1-9]|[12][0-9]|3[01])([- \/.])(0?[1-9]|1[012])([- \/.])((\d\d)?\d\d)$/, d:1, m:3, y:5 }, // dmy
\r
50 { regExp:/^(\d\d\d\d)([- \/.])(0?[1-9]|1[012])([- \/.])(0?[1-9]|[12][0-9]|3[01])$/, d:5, m:3, y:1 } // ymd
\r
55 var numFormats = dateTest.length;
\r
56 while(cnt < numFormats) {
\r
57 start = (cnt + (favourDMY ? numFormats + 1 : numFormats)) % numFormats;
\r
58 if(aa.match(dateTest[start].regExp)) {
\r
59 res = aa.match(dateTest[start].regExp);
\r
60 y = res[dateTest[start].y];
\r
61 m = res[dateTest[start].m];
\r
62 d = res[dateTest[start].d];
\r
63 if(m.length == 1) m = "0" + String(m);
\r
64 if(d.length == 1) d = "0" + String(d);
\r
65 if(y.length != 4) y = (parseInt(y) < 50) ? "20" + String(y) : "19" + String(y);
\r
67 return y+String(m)+d+String(timestamp);
\r
76 -----------------------
\r
78 This function sorts alphaNumeric values e.g. 1, e, 1a, -23c, 54z
\r
80 Notice how the prepareData function actually returns an Array i.e. you are not limited
\r
81 in the type of data you return to the tableSort script.
\r
83 function sortAlphaNumericPrepareData(tdNode, innerText){
\r
84 var aa = innerText.toLowerCase().replace(" ", "");
\r
85 var reg = /((\-|\+)?(\s+)?[0-9]+\.([0-9]+)?|(\-|\+)?(\s+)?(\.)?[0-9]+)([a-z]+)/;
\r
88 var aaP = aa.match(reg);
\r
89 return [aaP[1], aaP[8]];
\r
93 return isNaN(aa) ? ["",aa] : [aa,""];
\r
96 function sortAlphaNumeric(a, b){
\r
97 // Get the previously prepared array
\r
98 var aa = a[fdTableSort.pos];
\r
99 var bb = b[fdTableSort.pos];
\r
101 // If they are equal then return 0
\r
102 if(aa[0] == bb[0] && aa[1] == bb[1]) { return 0; };
\r
104 // Check numeric parts if not equal
\r
105 if(aa[0] != bb[0]) {
\r
106 if(aa[0] != "" && bb[0] != "") { return aa[0] - bb[0]; };
\r
107 if(aa[0] == "" && bb[0] != "") { return -1; };
\r
111 // Check alpha parts if numeric parts equal
\r
112 if(aa[1] == bb[1]) return 0;
\r
113 if(aa[1] < bb[1]) return -1;
\r
118 sortDutchCurrencyValues
\r
119 -----------------------
\r
121 This function sorts Dutch currency values (of the type 100.000,00)
\r
122 The function is "safe" i.e. non-currency data (like the word "Unknown") can be passed in and is sorted properly.
\r
124 var sortDutchCurrencyValues = fdTableSort.sortNumeric;
\r
126 function sortDutchCurrencyValuesPrepareData(tdNode, innerText) {
\r
127 innerText = parseInt(innerText.replace(/[^0-9\.,]+/g, "").replace(/\./g,"").replace(",","."));
\r
128 return isNaN(innerText) ? "" : innerText;
\r
132 sortByTwelveHourTimestamp
\r
133 -------------------------
\r
135 This custom sort function sorts 12 hour timestamps of an hour/minute nature.
\r
136 The hour/minute dividor can be a full-stop or a colon and it correctly calculates that 12.30am is before 1am etc
\r
137 The am/pm part can be written in lower or uppercase and can optionally contain full-stops e.g.
\r
139 am, a.m, a.m., AM, A.M etc
\r
141 Additionally, the values "12 midnight" and "12 noon" are also handled correctly.
\r
143 The question remains... does "12p.m." mean "midnight" or "12 noon"? I've decided here that it's 12 noon.
\r
145 The function is "safe" i.e. non-timestamp data (like the word "Unknown") can be passed in and is sorted properly.
\r
147 var sortByTwelveHourTimestamp = fdTableSort.sortNumeric;
\r
149 function sortByTwelveHourTimestampPrepareData(tdNode, innerText) {
\r
151 innerText = innerText.replace(":",".");
\r
153 // Check for the special cases of "12 noon" or "12 midnight"
\r
154 if(innerText.search(/12([\s]*)?noon/i) != -1) return "12.00";
\r
155 if(innerText.search(/12([\s]*)?midnight/i) != -1) return "24.00";
\r
157 var regExpPM = /^([0-9]{1,2}).([0-9]{2})([\s]*)?(p[\.]?m)/i;
\r
158 var regExpAM = /^([0-9]{1,2}).([0-9]{2})([\s]*)?(a[\.]?m)/i;
\r
160 if(innerText.search(regExpPM) != -1) {
\r
161 var bits = innerText.match(regExpPM);
\r
162 if(parseInt(bits[1]) < 12) { bits[1] = parseInt(bits[1]) + 12; }
\r
163 } else if(innerText.search(regExpAM) != -1) {
\r
164 var bits = innerText.match(regExpAM);
\r
165 if(bits[1] == "12") { bits[1] = "00"; }
\r
168 if(bits[2].length < 2) { bits[2] = "0" + String(bits[2]); }
\r
170 innerText = bits[1] + "." + String(bits[2]);
\r
172 return isNaN(innerText) ? "" : innerText;
\r
175 sortEnglishLonghandDateFormat
\r
176 -----------------------------
\r
178 This custom sort function sorts dates of the format:
\r
180 "12th April, 2006" or "12 April 2006" or "12-4-2006" or "12 April" or "12 4" or "12 Apr 2006" etc
\r
182 The function expects dates to be in the format day/month/year. Should no year be stipulated,
\r
183 the function treats the year as being the current year.
\r
185 The function is "safe" i.e. non-date data (like the word "Unknown") can be passed in and is sorted properly.
\r
187 var sortEnglishLonghandDateFormat = fdTableSort.sortNumeric;
\r
189 function sortEnglishLonghandDateFormatPrepareData(tdNode, innerText) {
\r
190 var months = ['january','february','march','april','may','june','july','august','september','october','november','december'];
\r
192 var aa = innerText.toLowerCase();
\r
194 // Replace the longhand months with an integer equivalent
\r
195 for(var i = 0; i < 12; i++) {
\r
196 aa = aa.replace(months[i], i+1).replace(months[i].substring(0,3), i+1);
\r
199 // If there are still alpha characters then return -1
\r
200 if(aa.search(/a-z/) != -1) return -1;
\r
202 // Replace multiple spaces and anything that is not numeric
\r
203 aa = aa.replace(/\s+/g, " ").replace(/[^\d\s]/g, "");
\r
205 // If were left with nothing then return -1
\r
206 if(aa.replace(" ", "") == "") return -1;
\r
208 // Split on the (now) single spaces
\r
209 aa = aa.split(" ");
\r
211 // If something has gone terribly wrong then return -1
\r
212 if(aa.length < 2) return -1;
\r
214 // If no year stipulated, then add this year as default
\r
215 if(aa.length == 2) {
\r
216 aa[2] = String(new Date().getFullYear());
\r
219 // Equalise the day and month
\r
220 if(aa[0].length < 2) aa[0] = "0" + String(aa[0]);
\r
221 if(aa[1].length < 2) aa[1] = "0" + String(aa[1]);
\r
223 // Deal with Y2K issues
\r
224 if(aa[2].length != 4) {
\r
225 aa[2] = (parseInt(aa[2]) < 50) ? '20' + aa[2] : '19' + aa[2];
\r
228 // YMD (can be used as integer during comparison)
\r
229 return aa[2] + String(aa[1]) + aa[0];
\r
235 This custom sort function correctly sorts IP addresses i.e. it checks all of the address parts and not just the first.
\r
237 The function is "safe" i.e. non-IP address data (like the word "Unknown") can be passed in and is sorted properly.
\r
239 var sortIPAddress = fdTableSort.sortNumeric;
\r
241 function sortIPAddressPrepareData(tdNode, innerText) {
\r
242 // Get the innerText of the TR nodes
\r
243 var aa = innerText;
\r
246 aa = aa.replace(" ","");
\r
248 // If not an IP address then return -1
\r
249 if(aa.search(/^([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3})$/) == -1) return -1;
\r
251 // Split on the "."
\r
252 aa = aa.split(".");
\r
254 // If we don't have 4 parts then return -1
\r
255 if(aa.length != 4) return -1;
\r
259 // Make all the parts an equal length and create a master integer
\r
260 for(var i = 0; i < 4; i++) {
\r
261 retVal += (String(aa[i]).length < 3) ? "0000".substr(0, 3 - String(aa[i]).length) + String(aa[i]) : aa[i];
\r
267 sortScientificNotation
\r
268 ----------------------
\r
270 This custom sort function sorts numbers stipulated in scientific notation
\r
272 The function is "safe" i.e. data like the word "Unknown" can be passed in and is sorted properly.
\r
274 N.B. The only way I can think to really sort scientific notation is to convert
\r
275 it to a floating point number and then perform the sort on that. If you can think of
\r
276 an easier/better way then please let me know.
\r
278 var sortScientificNotation = fdTableSort.sortNumeric;
\r
280 function sortScientificNotationPrepareData(tdNode, innerText) {
\r
281 var aa = innerText;
\r
283 var floatRegExp = /((\-|\+)?(\s+)?[0-9]+\.([0-9]+)?|(\-|\+)?(\s+)?(\.)?[0-9]+)/g;
\r
285 aa = aa.match(floatRegExp);
\r
287 if(!aa || aa.length != 2) return "";
\r
289 var f1 = parseFloat(aa[0].replace(" ",""))*Math.pow(10,parseFloat(aa[1].replace(" ","")));
\r
290 return isNaN(f1) ? "" : f1;
\r
297 This is the function called in order to sort the data previously prepared by the function
\r
298 "sortImagePrepareData". It does a basic case sensitive comparison on the data using the
\r
299 tableSort's in-built sortText method.
\r
301 var sortImage = fdTableSort.sortText;
\r
304 This is the function used to prepare i.e. parse data, to be used during the sort
\r
305 of the images within the last table.
\r
307 In this case, we are checking to see if the TD node has any child nodes that are
\r
308 images and, if an image exists, return it's "src" attribute.
\r
309 If no image exists, then we return an empty string.
\r
311 The "prepareData" functions are passed the actual TD node and also the TD node inner text
\r
312 which means you are free to check for child nodes etc and are not just limited to
\r
313 sorting on the TD node's inner text.
\r
315 The prepareData functions are not required (only your bespoke sort function is required)
\r
316 and only called by the script should they exist.
\r
318 function sortImagePrepareData(td, innerText) {
\r
319 var img = td.getElementsByTagName('img');
\r
320 return img.length ? img[0].src: "";
\r
328 1 Kilobyte = 1024 Bytes
\r
329 1 Megabyte = 1048576 Bytes
\r
330 1 Gigabyte = 1073741824 Bytes
\r
332 var sortFileSize = fdTableSort.sortNumeric;
\r
334 function sortFileSizePrepareData(td, innerText) {
\r
335 var regExp = /(kb|mb|gb)/i;
\r
337 var type = innerText.search(regExp) != -1 ? innerText.match(regExp)[0] : "";
\r
339 switch (type.toLowerCase()) {
\r
353 innerText = parseFloat(innerText.replace(/[^0-9\.\-]/g,''));
\r
355 return isNaN(innerText) ? "" : innerText * mult;
\r