--- /dev/null
+/*\r
+ sortEnglishDateTime\r
+ -----------------------\r
+\r
+ This function sorts English dateTime vaues such as:\r
+\r
+ 1st January 2003, 23:32:01\r
+ 23/03/1972 à 10:22:22\r
+ 1970/13/03 at 23:22:01\r
+ \r
+ The function is "safe" i.e. non-dateTime data (like the word "Unknown") can be passed in and is sorted properly.\r
+*/\r
+var sortEnglishDateTime = fdTableSort.sortNumeric;\r
+\r
+function sortEnglishDateTimePrepareData(tdNode, innerText) {\r
+ // You can localise the function here\r
+ 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
+\r
+ // Lowercase the text\r
+ var aa = innerText.toLowerCase();\r
+\r
+ // Replace the longhand months with an integer equivalent\r
+ for(var i = 0; i < months.length; i++) {\r
+ aa = aa.replace(months[i], (i+13)%12);\r
+ };\r
+\r
+ // Replace multiple spaces and anything that is not valid in the parsing of the date, then trim\r
+ aa = aa.replace(/\s+/g, " ").replace(/([^\d\s\/-:.])/g, "").replace(/^\s\s*/, '').replace(/\s\s*$/, '');\r
+\r
+ // No timestamp at the end, then return -1\r
+ if(aa.search(/(\d){2}:(\d){2}(:(\d){2})?$/) == -1) { return -1; };\r
+\r
+ // Grab the timestamp\r
+ var timestamp = aa.match(/(\d){2}:(\d){2}(:(\d){2})?$/)[0].replace(/:/g, "");\r
+\r
+ // Make the timestamp 6 characters by default\r
+ if(timestamp.length == 4) { timestamp += "00"; };\r
+\r
+ // Remove it from the string to assist the date parser, then trim\r
+ aa = aa.replace(/(\d){2}:(\d){2}(:(\d){2})?$/, "").replace(/\s\s*$/, '');\r
+\r
+ // If you want the parser to favour the parsing of European dd/mm/yyyy dates then leave this set to "true"\r
+ // If you want the parser to favour the parsing of American mm/dd/yyyy dates then set to "false"\r
+ var favourDMY = true;\r
+\r
+ // If you have a regular expression you wish to add, add the Object to the end of the array\r
+ var dateTest = [\r
+ { 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
+ { 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
+ { 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
+ ];\r
+\r
+ var start,y,m,d;\r
+ var cnt = 0;\r
+ var numFormats = dateTest.length;\r
+ while(cnt < numFormats) {\r
+ start = (cnt + (favourDMY ? numFormats + 1 : numFormats)) % numFormats;\r
+ if(aa.match(dateTest[start].regExp)) {\r
+ res = aa.match(dateTest[start].regExp);\r
+ y = res[dateTest[start].y];\r
+ m = res[dateTest[start].m];\r
+ d = res[dateTest[start].d];\r
+ if(m.length == 1) m = "0" + String(m);\r
+ if(d.length == 1) d = "0" + String(d);\r
+ if(y.length != 4) y = (parseInt(y) < 50) ? "20" + String(y) : "19" + String(y);\r
+\r
+ return y+String(m)+d+String(timestamp);\r
+ };\r
+ cnt++;\r
+ };\r
+ return -1;\r
+};\r
+\r
+/*\r
+ sortAlphaNumeric\r
+ -----------------------\r
+\r
+ This function sorts alphaNumeric values e.g. 1, e, 1a, -23c, 54z\r
+ \r
+ Notice how the prepareData function actually returns an Array i.e. you are not limited\r
+ in the type of data you return to the tableSort script.\r
+*/\r
+function sortAlphaNumericPrepareData(tdNode, innerText){\r
+ var aa = innerText.toLowerCase().replace(" ", "");\r
+ var reg = /((\-|\+)?(\s+)?[0-9]+\.([0-9]+)?|(\-|\+)?(\s+)?(\.)?[0-9]+)([a-z]+)/;\r
+\r
+ if(reg.test(aa)) {\r
+ var aaP = aa.match(reg);\r
+ return [aaP[1], aaP[8]];\r
+ };\r
+\r
+ // Return an array\r
+ return isNaN(aa) ? ["",aa] : [aa,""];\r
+}\r
+\r
+function sortAlphaNumeric(a, b){\r
+ // Get the previously prepared array\r
+ var aa = a[fdTableSort.pos];\r
+ var bb = b[fdTableSort.pos];\r
+\r
+ // If they are equal then return 0\r
+ if(aa[0] == bb[0] && aa[1] == bb[1]) { return 0; };\r
+\r
+ // Check numeric parts if not equal\r
+ if(aa[0] != bb[0]) {\r
+ if(aa[0] != "" && bb[0] != "") { return aa[0] - bb[0]; };\r
+ if(aa[0] == "" && bb[0] != "") { return -1; };\r
+ return 1;\r
+ };\r
+ \r
+ // Check alpha parts if numeric parts equal\r
+ if(aa[1] == bb[1]) return 0;\r
+ if(aa[1] < bb[1]) return -1;\r
+ return 1;\r
+}\r
+\r
+/*\r
+ sortDutchCurrencyValues\r
+ -----------------------\r
+\r
+ This function sorts Dutch currency values (of the type 100.000,00)\r
+ The function is "safe" i.e. non-currency data (like the word "Unknown") can be passed in and is sorted properly.\r
+*/\r
+var sortDutchCurrencyValues = fdTableSort.sortNumeric;\r
+\r
+function sortDutchCurrencyValuesPrepareData(tdNode, innerText) {\r
+ innerText = parseInt(innerText.replace(/[^0-9\.,]+/g, "").replace(/\./g,"").replace(",","."));\r
+ return isNaN(innerText) ? "" : innerText;\r
+}\r
+\r
+/*\r
+ sortByTwelveHourTimestamp\r
+ -------------------------\r
+\r
+ This custom sort function sorts 12 hour timestamps of an hour/minute nature.\r
+ The hour/minute dividor can be a full-stop or a colon and it correctly calculates that 12.30am is before 1am etc\r
+ The am/pm part can be written in lower or uppercase and can optionally contain full-stops e.g.\r
+\r
+ am, a.m, a.m., AM, A.M etc\r
+\r
+ Additionally, the values "12 midnight" and "12 noon" are also handled correctly.\r
+\r
+ The question remains... does "12p.m." mean "midnight" or "12 noon"? I've decided here that it's 12 noon.\r
+\r
+ The function is "safe" i.e. non-timestamp data (like the word "Unknown") can be passed in and is sorted properly.\r
+*/\r
+var sortByTwelveHourTimestamp = fdTableSort.sortNumeric;\r
+\r
+function sortByTwelveHourTimestampPrepareData(tdNode, innerText) {\r
+ tmp = innerText\r
+ innerText = innerText.replace(":",".");\r
+\r
+ // Check for the special cases of "12 noon" or "12 midnight"\r
+ if(innerText.search(/12([\s]*)?noon/i) != -1) return "12.00";\r
+ if(innerText.search(/12([\s]*)?midnight/i) != -1) return "24.00";\r
+\r
+ var regExpPM = /^([0-9]{1,2}).([0-9]{2})([\s]*)?(p[\.]?m)/i;\r
+ var regExpAM = /^([0-9]{1,2}).([0-9]{2})([\s]*)?(a[\.]?m)/i;\r
+\r
+ if(innerText.search(regExpPM) != -1) {\r
+ var bits = innerText.match(regExpPM);\r
+ if(parseInt(bits[1]) < 12) { bits[1] = parseInt(bits[1]) + 12; }\r
+ } else if(innerText.search(regExpAM) != -1) {\r
+ var bits = innerText.match(regExpAM);\r
+ if(bits[1] == "12") { bits[1] = "00"; }\r
+ } else return "";\r
+\r
+ if(bits[2].length < 2) { bits[2] = "0" + String(bits[2]); }\r
+\r
+ innerText = bits[1] + "." + String(bits[2]);\r
+\r
+ return isNaN(innerText) ? "" : innerText;\r
+}\r
+/*\r
+ sortEnglishLonghandDateFormat\r
+ -----------------------------\r
+\r
+ This custom sort function sorts dates of the format:\r
+\r
+ "12th April, 2006" or "12 April 2006" or "12-4-2006" or "12 April" or "12 4" or "12 Apr 2006" etc\r
+\r
+ The function expects dates to be in the format day/month/year. Should no year be stipulated,\r
+ the function treats the year as being the current year.\r
+\r
+ The function is "safe" i.e. non-date data (like the word "Unknown") can be passed in and is sorted properly.\r
+*/\r
+var sortEnglishLonghandDateFormat = fdTableSort.sortNumeric;\r
+\r
+function sortEnglishLonghandDateFormatPrepareData(tdNode, innerText) {\r
+ var months = ['january','february','march','april','may','june','july','august','september','october','november','december'];\r
+\r
+ var aa = innerText.toLowerCase();\r
+\r
+ // Replace the longhand months with an integer equivalent\r
+ for(var i = 0; i < 12; i++) {\r
+ aa = aa.replace(months[i], i+1).replace(months[i].substring(0,3), i+1);\r
+ }\r
+\r
+ // If there are still alpha characters then return -1\r
+ if(aa.search(/a-z/) != -1) return -1;\r
+\r
+ // Replace multiple spaces and anything that is not numeric\r
+ aa = aa.replace(/\s+/g, " ").replace(/[^\d\s]/g, "");\r
+\r
+ // If were left with nothing then return -1\r
+ if(aa.replace(" ", "") == "") return -1;\r
+\r
+ // Split on the (now) single spaces\r
+ aa = aa.split(" ");\r
+\r
+ // If something has gone terribly wrong then return -1\r
+ if(aa.length < 2) return -1;\r
+\r
+ // If no year stipulated, then add this year as default\r
+ if(aa.length == 2) {\r
+ aa[2] = String(new Date().getFullYear());\r
+ }\r
+\r
+ // Equalise the day and month\r
+ if(aa[0].length < 2) aa[0] = "0" + String(aa[0]);\r
+ if(aa[1].length < 2) aa[1] = "0" + String(aa[1]);\r
+\r
+ // Deal with Y2K issues\r
+ if(aa[2].length != 4) {\r
+ aa[2] = (parseInt(aa[2]) < 50) ? '20' + aa[2] : '19' + aa[2];\r
+ }\r
+\r
+ // YMD (can be used as integer during comparison)\r
+ return aa[2] + String(aa[1]) + aa[0];\r
+}\r
+/*\r
+ sortIPAddress\r
+ -------------\r
+\r
+ This custom sort function correctly sorts IP addresses i.e. it checks all of the address parts and not just the first.\r
+\r
+ The function is "safe" i.e. non-IP address data (like the word "Unknown") can be passed in and is sorted properly.\r
+*/\r
+var sortIPAddress = fdTableSort.sortNumeric;\r
+\r
+function sortIPAddressPrepareData(tdNode, innerText) {\r
+ // Get the innerText of the TR nodes\r
+ var aa = innerText;\r
+\r
+ // Remove spaces\r
+ aa = aa.replace(" ","");\r
+\r
+ // If not an IP address then return -1\r
+ if(aa.search(/^([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3})$/) == -1) return -1;\r
+\r
+ // Split on the "."\r
+ aa = aa.split(".");\r
+\r
+ // If we don't have 4 parts then return -1\r
+ if(aa.length != 4) return -1;\r
+\r
+ var retVal = "";\r
+\r
+ // Make all the parts an equal length and create a master integer\r
+ for(var i = 0; i < 4; i++) {\r
+ retVal += (String(aa[i]).length < 3) ? "0000".substr(0, 3 - String(aa[i]).length) + String(aa[i]) : aa[i];\r
+ }\r
+\r
+ return retVal;\r
+}\r
+/*\r
+ sortScientificNotation\r
+ ----------------------\r
+\r
+ This custom sort function sorts numbers stipulated in scientific notation\r
+\r
+ The function is "safe" i.e. data like the word "Unknown" can be passed in and is sorted properly.\r
+\r
+ N.B. The only way I can think to really sort scientific notation is to convert\r
+ it to a floating point number and then perform the sort on that. If you can think of\r
+ an easier/better way then please let me know.\r
+*/\r
+var sortScientificNotation = fdTableSort.sortNumeric;\r
+\r
+function sortScientificNotationPrepareData(tdNode, innerText) {\r
+ var aa = innerText;\r
+\r
+ var floatRegExp = /((\-|\+)?(\s+)?[0-9]+\.([0-9]+)?|(\-|\+)?(\s+)?(\.)?[0-9]+)/g;\r
+\r
+ aa = aa.match(floatRegExp);\r
+\r
+ if(!aa || aa.length != 2) return "";\r
+\r
+ var f1 = parseFloat(aa[0].replace(" ",""))*Math.pow(10,parseFloat(aa[1].replace(" ","")));\r
+ return isNaN(f1) ? "" : f1;\r
+}\r
+\r
+/*\r
+ sortImage\r
+ ---------\r
+\r
+ This is the function called in order to sort the data previously prepared by the function\r
+ "sortImagePrepareData". It does a basic case sensitive comparison on the data using the\r
+ tableSort's in-built sortText method.\r
+*/\r
+var sortImage = fdTableSort.sortText;\r
+\r
+/*\r
+ This is the function used to prepare i.e. parse data, to be used during the sort\r
+ of the images within the last table.\r
+\r
+ In this case, we are checking to see if the TD node has any child nodes that are\r
+ images and, if an image exists, return it's "src" attribute.\r
+ If no image exists, then we return an empty string.\r
+\r
+ The "prepareData" functions are passed the actual TD node and also the TD node inner text\r
+ which means you are free to check for child nodes etc and are not just limited to\r
+ sorting on the TD node's inner text.\r
+\r
+ The prepareData functions are not required (only your bespoke sort function is required)\r
+ and only called by the script should they exist.\r
+*/\r
+function sortImagePrepareData(td, innerText) {\r
+ var img = td.getElementsByTagName('img');\r
+ return img.length ? img[0].src: "";\r
+}\r
+\r
+/*\r
+ sortFileSize\r
+ ------------\r
+\r
+ 1 Byte = 8 Bit\r
+ 1 Kilobyte = 1024 Bytes\r
+ 1 Megabyte = 1048576 Bytes\r
+ 1 Gigabyte = 1073741824 Bytes\r
+*/\r
+var sortFileSize = fdTableSort.sortNumeric;\r
+\r
+function sortFileSizePrepareData(td, innerText) {\r
+ var regExp = /(kb|mb|gb)/i;\r
+\r
+ var type = innerText.search(regExp) != -1 ? innerText.match(regExp)[0] : "";\r
+\r
+ switch (type.toLowerCase()) {\r
+ case "kb" :\r
+ mult = 1024;\r
+ break;\r
+ case "mb" :\r
+ mult = 1048576;\r
+ break;\r
+ case "gb" :\r
+ mult = 1073741824;\r
+ break;\r
+ default :\r
+ mult = 1;\r
+ };\r
+\r
+ innerText = parseFloat(innerText.replace(/[^0-9\.\-]/g,''));\r
+\r
+ return isNaN(innerText) ? "" : innerText * mult;\r
+};\r