JAVASCRIPT   23

jquery scrollbox js

Guest on 21st June 2022 01:53:03 AM

  1. /*
  2.  *
  3.  * TableSorter 2.0 - Client-side table sorting with ease!
  4.  * Version 2.0.5b
  5.  * @requires jQuery v1.2.3
  6.  *
  7.  * Copyright (c) 2007 Christian Bach
  8.  * Examples and docs at: http://tablesorter.com
  9.  * Dual licensed under the MIT and GPL licenses:
  10.  * http://www.opensource.org/licenses/mit-license.php
  11.  * http://www.gnu.org/licenses/gpl.html
  12.  *
  13.  */
  14. /**
  15.  *
  16.  * @description Create a sortable table with multi-column sorting capabilitys
  17.  *
  18.  * @example $('table').tablesorter();
  19.  * @desc Create a simple tablesorter interface.
  20.  *
  21.  * @example $('table').tablesorter({ sortList:[[0,0],[1,0]] });
  22.  * @desc Create a tablesorter interface and sort on the first and secound column column headers.
  23.  *
  24.  * @example $('table').tablesorter({ headers: { 0: { sorter: false}, 1: {sorter: false} } });
  25.  *          
  26.  * @desc Create a tablesorter interface and disableing the first and second  column headers.
  27.  *      
  28.  *
  29.  * @example $('table').tablesorter({ headers: { 0: {sorter:"integer"}, 1: {sorter:"currency"} } });
  30.  *
  31.  * @desc Create a tablesorter interface and set a column parser for the first
  32.  *       and second column.
  33.  *
  34.  *
  35.  * @param Object
  36.  *            settings An object literal containing key/value pairs to provide
  37.  *            optional settings.
  38.  *
  39.  *
  40.  * @option String cssHeader (optional) A string of the class name to be appended
  41.  *         to sortable tr elements in the thead of the table. Default value:
  42.  *         "header"
  43.  *
  44.  * @option String cssAsc (optional) A string of the class name to be appended to
  45.  *         sortable tr elements in the thead on a ascending sort. Default value:
  46.  *         "headerSortUp"
  47.  *
  48.  * @option String cssDesc (optional) A string of the class name to be appended
  49.  *         to sortable tr elements in the thead on a descending sort. Default
  50.  *         value: "headerSortDown"
  51.  *
  52.  * @option String sortInitialOrder (optional) A string of the inital sorting
  53.  *         order can be asc or desc. Default value: "asc"
  54.  *
  55.  * @option String sortMultisortKey (optional) A string of the multi-column sort
  56.  *         key. Default value: "shiftKey"
  57.  *
  58.  * @option String textExtraction (optional) A string of the text-extraction
  59.  *         method to use. For complex html structures inside td cell set this
  60.  *         option to "complex", on large tables the complex option can be slow.
  61.  *         Default value: "simple"
  62.  *
  63.  * @option Object headers (optional) An array containing the forces sorting
  64.  *         rules. This option let's you specify a default sorting rule. Default
  65.  *         value: null
  66.  *
  67.  * @option Array sortList (optional) An array containing the forces sorting
  68.  *         rules. This option let's you specify a default sorting rule. Default
  69.  *         value: null
  70.  *
  71.  * @option Array sortForce (optional) An array containing forced sorting rules.
  72.  *         This option let's you specify a default sorting rule, which is
  73.  *         prepended to user-selected rules. Default value: null
  74.  *
  75.  * @option Boolean sortLocaleCompare (optional) Boolean flag indicating whatever
  76.  *         to use String.localeCampare method or not. Default set to true.
  77.  *
  78.  *
  79.  * @option Array sortAppend (optional) An array containing forced sorting rules.
  80.  *         This option let's you specify a default sorting rule, which is
  81.  *         appended to user-selected rules. Default value: null
  82.  *
  83.  * @option Boolean widthFixed (optional) Boolean flag indicating if tablesorter
  84.  *         should apply fixed widths to the table columns. This is usefull when
  85.  *         using the pager companion plugin. This options requires the dimension
  86.  *         jquery plugin. Default value: false
  87.  *
  88.  * @option Boolean cancelSelection (optional) Boolean flag indicating if
  89.  *         tablesorter should cancel selection of the table headers text.
  90.  *         Default value: true
  91.  *
  92.  * @option Boolean debug (optional) Boolean flag indicating if tablesorter
  93.  *         should display debuging information usefull for development.
  94.  *
  95.  * @type jQuery
  96.  *
  97.  * @name tablesorter
  98.  *
  99.  * @cat Plugins/Tablesorter
  100.  *
  101.  * @author Christian Bach/christian.bach@polyester.se
  102.  */
  103.  
  104. (function ($) {
  105.     $.extend({
  106.         tablesorter: new
  107.         function () {
  108.  
  109.             var parsers = [],
  110.                 widgets = [];
  111.  
  112.             this.defaults = {
  113.                 cssHeader: "header",
  114.                 cssAsc: "headerSortUp",
  115.                 cssDesc: "headerSortDown",
  116.                 cssChildRow: "expand-child",
  117.                 sortInitialOrder: "asc",
  118.                 sortMultiSortKey: "shiftKey",
  119.                 sortForce: null,
  120.                 sortAppend: null,
  121.                 sortLocaleCompare: true,
  122.                 textExtraction: "simple",
  123.                 parsers: {}, widgets: [],
  124.                 widgetZebra: {
  125.                     css: ["even", "odd"]
  126.                 }, headers: {}, widthFixed: false,
  127.                 cancelSelection: true,
  128.                 sortList: [],
  129.                 headerList: [],
  130.                 dateFormat: "us",
  131.                 decimal: '/\.|\,/g',
  132.                 onRenderHeader: null,
  133.                 selectorHeaders: 'thead th',
  134.                 debug: false
  135.             };
  136.  
  137.             /* debuging utils */
  138.  
  139.             function benchmark(s, d) {
  140.                 log(s + "," + (new Date().getTime() - d.getTime()) + "ms");
  141.             }
  142.  
  143.             this.benchmark = benchmark;
  144.  
  145.             function log(s) {
  146.                 if (typeof console != "undefined" && typeof console.debug != "undefined") {
  147.                     console.log(s);
  148.                 } else {
  149.                     alert(s);
  150.                 }
  151.             }
  152.  
  153.             /* parsers utils */
  154.  
  155.             function buildParserCache(table, $headers) {
  156.  
  157.                 if (table.config.debug) {
  158.                     var parsersDebug = "";
  159.                 }
  160.  
  161.                 if (table.tBodies.length == 0) return; // In the case of empty tables
  162.                 var rows = table.tBodies[0].rows;
  163.  
  164.                 if (rows[0]) {
  165.  
  166.                     var list = [],
  167.                         cells = rows[0].cells,
  168.                         l = cells.length;
  169.  
  170.                     for (var i = 0; i < l; i++) {
  171.  
  172.                         var p = false;
  173.  
  174.                         if ($.metadata && ($($headers[i]).metadata() && $($headers[i]).metadata().sorter)) {
  175.  
  176.                             p = getParserById($($headers[i]).metadata().sorter);
  177.  
  178.                         } else if ((table.config.headers[i] && table.config.headers[i].sorter)) {
  179.  
  180.                             p = getParserById(table.config.headers[i].sorter);
  181.                         }
  182.                         if (!p) {
  183.  
  184.                             p = detectParserForColumn(table, rows, -1, i);
  185.                         }
  186.  
  187.                         if (table.config.debug) {
  188.                             parsersDebug += "column:" + i + " parser:" + p.id + "\n";
  189.                         }
  190.  
  191.                         list.push(p);
  192.                     }
  193.                 }
  194.  
  195.                 if (table.config.debug) {
  196.                     log(parsersDebug);
  197.                 }
  198.  
  199.                 return list;
  200.             };
  201.  
  202.             function detectParserForColumn(table, rows, rowIndex, cellIndex) {
  203.                 var l = parsers.length,
  204.                     node = false,
  205.                     nodeValue = false,
  206.                     keepLooking = true;
  207.                 while (nodeValue == '' && keepLooking) {
  208.                     rowIndex++;
  209.                     if (rows[rowIndex]) {
  210.                         node = getNodeFromRowAndCellIndex(rows, rowIndex, cellIndex);
  211.                         nodeValue = trimAndGetNodeText(table.config, node);
  212.                         if (table.config.debug) {
  213.                             log('Checking if value was empty on row:' + rowIndex);
  214.                         }
  215.                     } else {
  216.                         keepLooking = false;
  217.                     }
  218.                 }
  219.                 for (var i = 1; i < l; i++) {
  220.                     if (parsers[i].is(nodeValue, table, node)) {
  221.                         return parsers[i];
  222.                     }
  223.                 }
  224.                 // 0 is always the generic parser (text)
  225.                 return parsers[0];
  226.             }
  227.  
  228.             function getNodeFromRowAndCellIndex(rows, rowIndex, cellIndex) {
  229.                 return rows[rowIndex].cells[cellIndex];
  230.             }
  231.  
  232.             function trimAndGetNodeText(config, node) {
  233.                 return $.trim(getElementText(config, node));
  234.             }
  235.  
  236.             function getParserById(name) {
  237.                 var l = parsers.length;
  238.                 for (var i = 0; i < l; i++) {
  239.                     if (parsers[i].id.toLowerCase() == name.toLowerCase()) {
  240.                         return parsers[i];
  241.                     }
  242.                 }
  243.                 return false;
  244.             }
  245.  
  246.             /* utils */
  247.  
  248.             function buildCache(table) {
  249.  
  250.                 if (table.config.debug) {
  251.                     var cacheTime = new Date();
  252.                 }
  253.  
  254.                 var totalRows = (table.tBodies[0] && table.tBodies[0].rows.length) || 0,
  255.                     totalCells = (table.tBodies[0].rows[0] && table.tBodies[0].rows[0].cells.length) || 0,
  256.                     parsers = table.config.parsers,
  257.                     cache = {
  258.                         row: [],
  259.                         normalized: []
  260.                     };
  261.  
  262.                 for (var i = 0; i < totalRows; ++i) {
  263.  
  264.                     /** Add the table data to main data array */
  265.                     var c = $(table.tBodies[0].rows[i]),
  266.                         cols = [];
  267.  
  268.                     // if this is a child row, add it to the last row's children and
  269.                     // continue to the next row
  270.                     if (c.hasClass(table.config.cssChildRow)) {
  271.                         cache.row[cache.row.length - 1] = cache.row[cache.row.length - 1].add(c);
  272.                         // go to the next for loop
  273.                         continue;
  274.                     }
  275.  
  276.                     cache.row.push(c);
  277.  
  278.                     for (var j = 0; j < totalCells; ++j) {
  279.                         cols.push(parsers[j].format(getElementText(table.config, c[0].cells[j]), table, c[0].cells[j]));
  280.                     }
  281.  
  282.                     cols.push(cache.normalized.length); // add position for rowCache
  283.                     cache.normalized.push(cols);
  284.                     cols = null;
  285.                 };
  286.  
  287.                 if (table.config.debug) {
  288.                     benchmark("Building cache for " + totalRows + " rows:", cacheTime);
  289.                 }
  290.  
  291.                 return cache;
  292.             };
  293.  
  294.             function getElementText(config, node) {
  295.  
  296.                 var text = "";
  297.  
  298.                 if (!node) return "";
  299.  
  300.                 if (!config.supportsTextContent) config.supportsTextContent = node.textContent || false;
  301.  
  302.                 if (config.textExtraction == "simple") {
  303.                     if (config.supportsTextContent) {
  304.                         text = node.textContent;
  305.                     } else {
  306.                         if (node.childNodes[0] && node.childNodes[0].hasChildNodes()) {
  307.                             text = node.childNodes[0].innerHTML;
  308.                         } else {
  309.                             text = node.innerHTML;
  310.                         }
  311.                     }
  312.                 } else {
  313.                     if (typeof(config.textExtraction) == "function") {
  314.                         text = config.textExtraction(node);
  315.                     } else {
  316.                         text = $(node).text();
  317.                     }
  318.                 }
  319.                 return text;
  320.             }
  321.  
  322.             function appendToTable(table, cache) {
  323.  
  324.                 if (table.config.debug) {
  325.                     var appendTime = new Date()
  326.                 }
  327.  
  328.                 var c = cache,
  329.                     r = c.row,
  330.                     n = c.normalized,
  331.                     totalRows = n.length,
  332.                     checkCell = (n[0].length - 1),
  333.                     tableBody = $(table.tBodies[0]),
  334.                     rows = [];
  335.  
  336.  
  337.                 for (var i = 0; i < totalRows; i++) {
  338.                     var pos = n[i][checkCell];
  339.  
  340.                     rows.push(r[pos]);
  341.  
  342.                     if (!table.config.appender) {
  343.  
  344.                         //var o = ;
  345.                         var l = r[pos].length;
  346.                         for (var j = 0; j < l; j++) {
  347.                             tableBody[0].appendChild(r[pos][j]);
  348.                         }
  349.  
  350.                         //
  351.                     }
  352.                 }
  353.  
  354.  
  355.  
  356.                 if (table.config.appender) {
  357.  
  358.                     table.config.appender(table, rows);
  359.                 }
  360.  
  361.                 rows = null;
  362.  
  363.                 if (table.config.debug) {
  364.                     benchmark("Rebuilt table:", appendTime);
  365.                 }
  366.  
  367.                 // apply table widgets
  368.                 applyWidget(table);
  369.  
  370.                 // trigger sortend
  371.                 setTimeout(function () {
  372.                     $(table).trigger("sortEnd");
  373.                 }, 0);
  374.  
  375.             };
  376.  
  377.             function buildHeaders(table) {
  378.  
  379.                 if (table.config.debug) {
  380.                     var time = new Date();
  381.                 }
  382.  
  383.                 var meta = ($.metadata) ? true : false;
  384.                
  385.                 var header_index = computeTableHeaderCellIndexes(table);
  386.  
  387.                 $tableHeaders = $(table.config.selectorHeaders, table).each(function (index) {
  388.  
  389.                     this.column = header_index[this.parentNode.rowIndex + "-" + this.cellIndex];
  390.                     // this.column = index;
  391.                     this.order = formatSortingOrder(table.config.sortInitialOrder);
  392.                    
  393.                                        
  394.                                         this.count = this.order;
  395.  
  396.                     if (checkHeaderMetadata(this) || checkHeaderOptions(table, index)) this.sortDisabled = true;
  397.                                         if (checkHeaderOptionsSortingLocked(table, index)) this.order = this.lockedOrder = checkHeaderOptionsSortingLocked(table, index);
  398.  
  399.                     if (!this.sortDisabled) {
  400.                         var $th = $(this).addClass(table.config.cssHeader);
  401.                         if (table.config.onRenderHeader) table.config.onRenderHeader.apply($th);
  402.                     }
  403.  
  404.                     // add cell to headerList
  405.                     table.config.headerList[index] = this;
  406.                 });
  407.  
  408.                 if (table.config.debug) {
  409.                     benchmark("Built headers:", time);
  410.                     log($tableHeaders);
  411.                 }
  412.  
  413.                 return $tableHeaders;
  414.  
  415.             };
  416.  
  417.             // from:
  418.             // http://www.javascripttoolbox.com/lib/table/examples.php
  419.             // http://www.javascripttoolbox.com/temp/table_cellindex.html
  420.  
  421.  
  422.             function computeTableHeaderCellIndexes(t) {
  423.                 var matrix = [];
  424.                 var lookup = {};
  425.                 var thead = t.getElementsByTagName('THEAD')[0];
  426.                 var trs = thead.getElementsByTagName('TR');
  427.  
  428.                 for (var i = 0; i < trs.length; i++) {
  429.                     var cells = trs[i].cells;
  430.                     for (var j = 0; j < cells.length; j++) {
  431.                         var c = cells[j];
  432.  
  433.                         var rowIndex = c.parentNode.rowIndex;
  434.                         var cellId = rowIndex + "-" + c.cellIndex;
  435.                         var rowSpan = c.rowSpan || 1;
  436.                         var colSpan = c.colSpan || 1
  437.                         var firstAvailCol;
  438.                         if (typeof(matrix[rowIndex]) == "undefined") {
  439.                             matrix[rowIndex] = [];
  440.                         }
  441.                         // Find first available column in the first row
  442.                         for (var k = 0; k < matrix[rowIndex].length + 1; k++) {
  443.                             if (typeof(matrix[rowIndex][k]) == "undefined") {
  444.                                 firstAvailCol = k;
  445.                                 break;
  446.                             }
  447.                         }
  448.                         lookup[cellId] = firstAvailCol;
  449.                         for (var k = rowIndex; k < rowIndex + rowSpan; k++) {
  450.                             if (typeof(matrix[k]) == "undefined") {
  451.                                 matrix[k] = [];
  452.                             }
  453.                             var matrixrow = matrix[k];
  454.                             for (var l = firstAvailCol; l < firstAvailCol + colSpan; l++) {
  455.                                 matrixrow[l] = "x";
  456.                             }
  457.                         }
  458.                     }
  459.                 }
  460.                 return lookup;
  461.             }
  462.  
  463.             function checkCellColSpan(table, rows, row) {
  464.                 var arr = [],
  465.                     r = table.tHead.rows,
  466.                     c = r[row].cells;
  467.  
  468.                 for (var i = 0; i < c.length; i++) {
  469.                     var cell = c[i];
  470.  
  471.                     if (cell.colSpan > 1) {
  472.                         arr = arr.concat(checkCellColSpan(table, headerArr, row++));
  473.                     } else {
  474.                         if (table.tHead.length == 1 || (cell.rowSpan > 1 || !r[row + 1])) {
  475.                             arr.push(cell);
  476.                         }
  477.                         // headerArr[row] = (i+row);
  478.                     }
  479.                 }
  480.                 return arr;
  481.             };
  482.  
  483.             function checkHeaderMetadata(cell) {
  484.                 if (($.metadata) && ($(cell).metadata().sorter === false)) {
  485.                     return true;
  486.                 };
  487.                 return false;
  488.             }
  489.  
  490.             function checkHeaderOptions(table, i) {
  491.                 if ((table.config.headers[i]) && (table.config.headers[i].sorter === false)) {
  492.                     return true;
  493.                 };
  494.                 return false;
  495.             }
  496.                        
  497.                          function checkHeaderOptionsSortingLocked(table, i) {
  498.                 if ((table.config.headers[i]) && (table.config.headers[i].lockedOrder)) return table.config.headers[i].lockedOrder;
  499.                 return false;
  500.             }
  501.                        
  502.             function applyWidget(table) {
  503.                 var c = table.config.widgets;
  504.                 var l = c.length;
  505.                 for (var i = 0; i < l; i++) {
  506.  
  507.                     getWidgetById(c[i]).format(table);
  508.                 }
  509.  
  510.             }
  511.  
  512.             function getWidgetById(name) {
  513.                 var l = widgets.length;
  514.                 for (var i = 0; i < l; i++) {
  515.                     if (widgets[i].id.toLowerCase() == name.toLowerCase()) {
  516.                         return widgets[i];
  517.                     }
  518.                 }
  519.             };
  520.  
  521.             function formatSortingOrder(v) {
  522.                 if (typeof(v) != "Number") {
  523.                     return (v.toLowerCase() == "desc") ? 1 : 0;
  524.                 } else {
  525.                     return (v == 1) ? 1 : 0;
  526.                 }
  527.             }
  528.  
  529.             function isValueInArray(v, a) {
  530.                 var l = a.length;
  531.                 for (var i = 0; i < l; i++) {
  532.                     if (a[i][0] == v) {
  533.                         return true;
  534.                     }
  535.                 }
  536.                 return false;
  537.             }
  538.  
  539.             function setHeadersCss(table, $headers, list, css) {
  540.                 // remove all header information
  541.                 $headers.removeClass(css[0]).removeClass(css[1]);
  542.  
  543.                 var h = [];
  544.                 $headers.each(function (offset) {
  545.                     if (!this.sortDisabled) {
  546.                         h[this.column] = $(this);
  547.                     }
  548.                 });
  549.  
  550.                 var l = list.length;
  551.                 for (var i = 0; i < l; i++) {
  552.                     h[list[i][0]].addClass(css[list[i][1]]);
  553.                 }
  554.             }
  555.  
  556.             function fixColumnWidth(table, $headers) {
  557.                 var c = table.config;
  558.                 if (c.widthFixed) {
  559.                     var colgroup = $('<colgroup>');
  560.                     $("tr:first td", table.tBodies[0]).each(function () {
  561.                         colgroup.append($('<col>').css('width', $(this).width()));
  562.                     });
  563.                     $(table).prepend(colgroup);
  564.                 };
  565.             }
  566.  
  567.             function updateHeaderSortCount(table, sortList) {
  568.                 var c = table.config,
  569.                     l = sortList.length;
  570.                 for (var i = 0; i < l; i++) {
  571.                     var s = sortList[i],
  572.                         o = c.headerList[s[0]];
  573.                     o.count = s[1];
  574.                     o.count++;
  575.                 }
  576.             }
  577.  
  578.             /* sorting methods */
  579.  
  580.             function multisort(table, sortList, cache) {
  581.  
  582.                 if (table.config.debug) {
  583.                     var sortTime = new Date();
  584.                 }
  585.  
  586.                 var dynamicExp = "var sortWrapper = function(a,b) {",
  587.                     l = sortList.length;
  588.  
  589.                 // TODO: inline functions.
  590.                 for (var i = 0; i < l; i++) {
  591.  
  592.                     var c = sortList[i][0];
  593.                     var order = sortList[i][1];
  594.                     // var s = (getCachedSortType(table.config.parsers,c) == "text") ?
  595.                     // ((order == 0) ? "sortText" : "sortTextDesc") : ((order == 0) ?
  596.                     // "sortNumeric" : "sortNumericDesc");
  597.                     // var s = (table.config.parsers[c].type == "text") ? ((order == 0)
  598.                     // ? makeSortText(c) : makeSortTextDesc(c)) : ((order == 0) ?
  599.                     // makeSortNumeric(c) : makeSortNumericDesc(c));
  600.                     var s = (table.config.parsers[c].type == "text") ? ((order == 0) ? makeSortFunction("text", "asc", c) : makeSortFunction("text", "desc", c)) : ((order == 0) ? makeSortFunction("numeric", "asc", c) : makeSortFunction("numeric", "desc", c));
  601.                     var e = "e" + i;
  602.  
  603.                     dynamicExp += "var " + e + " = " + s; // + "(a[" + c + "],b[" + c
  604.                     // + "]); ";
  605.                     dynamicExp += "if(" + e + ") { return " + e + "; } ";
  606.                     dynamicExp += "else { ";
  607.  
  608.                 }
  609.  
  610.                 // if value is the same keep orignal order
  611.                 var orgOrderCol = cache.normalized[0].length - 1;
  612.                 dynamicExp += "return a[" + orgOrderCol + "]-b[" + orgOrderCol + "];";
  613.  
  614.                 for (var i = 0; i < l; i++) {
  615.                     dynamicExp += "}; ";
  616.                 }
  617.  
  618.                 dynamicExp += "return 0; ";
  619.                 dynamicExp += "}; ";
  620.  
  621.                 if (table.config.debug) {
  622.                     benchmark("Evaling expression:" + dynamicExp, new Date());
  623.                 }
  624.  
  625.                 eval(dynamicExp);
  626.  
  627.                 cache.normalized.sort(sortWrapper);
  628.  
  629.                 if (table.config.debug) {
  630.                     benchmark("Sorting on " + sortList.toString() + " and dir " + order + " time:", sortTime);
  631.                 }
  632.  
  633.                 return cache;
  634.             };
  635.  
  636.             function makeSortFunction(type, direction, index) {
  637.                 var a = "a[" + index + "]",
  638.                     b = "b[" + index + "]";
  639.                 if (type == 'text' && direction == 'asc') {
  640.                     return "(" + a + " == " + b + " ? 0 : (" + a + " === null ? Number.POSITIVE_INFINITY : (" + b + " === null ? Number.NEGATIVE_INFINITY : (" + a + " < " + b + ") ? -1 : 1 )));";
  641.                 } else if (type == 'text' && direction == 'desc') {
  642.                     return "(" + a + " == " + b + " ? 0 : (" + a + " === null ? Number.POSITIVE_INFINITY : (" + b + " === null ? Number.NEGATIVE_INFINITY : (" + b + " < " + a + ") ? -1 : 1 )));";
  643.                 } else if (type == 'numeric' && direction == 'asc') {
  644.                     return "(" + a + " === null && " + b + " === null) ? 0 :(" + a + " === null ? Number.POSITIVE_INFINITY : (" + b + " === null ? Number.NEGATIVE_INFINITY : " + a + " - " + b + "));";
  645.                 } else if (type == 'numeric' && direction == 'desc') {
  646.                     return "(" + a + " === null && " + b + " === null) ? 0 :(" + a + " === null ? Number.POSITIVE_INFINITY : (" + b + " === null ? Number.NEGATIVE_INFINITY : " + b + " - " + a + "));";
  647.                 }
  648.             };
  649.  
  650.             function makeSortText(i) {
  651.                 return "((a[" + i + "] < b[" + i + "]) ? -1 : ((a[" + i + "] > b[" + i + "]) ? 1 : 0));";
  652.             };
  653.  
  654.             function makeSortTextDesc(i) {
  655.                 return "((b[" + i + "] < a[" + i + "]) ? -1 : ((b[" + i + "] > a[" + i + "]) ? 1 : 0));";
  656.             };
  657.  
  658.             function makeSortNumeric(i) {
  659.                 return "a[" + i + "]-b[" + i + "];";
  660.             };
  661.  
  662.             function makeSortNumericDesc(i) {
  663.                 return "b[" + i + "]-a[" + i + "];";
  664.             };
  665.  
  666.             function sortText(a, b) {
  667.                 if (table.config.sortLocaleCompare) return a.localeCompare(b);
  668.                 return ((a < b) ? -1 : ((a > b) ? 1 : 0));
  669.             };
  670.  
  671.             function sortTextDesc(a, b) {
  672.                 if (table.config.sortLocaleCompare) return b.localeCompare(a);
  673.                 return ((b < a) ? -1 : ((b > a) ? 1 : 0));
  674.             };
  675.  
  676.             function sortNumeric(a, b) {
  677.                 return a - b;
  678.             };
  679.  
  680.             function sortNumericDesc(a, b) {
  681.                 return b - a;
  682.             };
  683.  
  684.             function getCachedSortType(parsers, i) {
  685.                 return parsers[i].type;
  686.             }; /* public methods */
  687.             this.construct = function (settings) {
  688.                 return this.each(function () {
  689.                     // if no thead or tbody quit.
  690.                     if (!this.tHead || !this.tBodies) return;
  691.                     // declare
  692.                     var $this, $document, $headers, cache, config, shiftDown = 0,
  693.                         sortOrder;
  694.                     // new blank config object
  695.                     this.config = {};
  696.                     // merge and extend.
  697.                     config = $.extend(this.config, $.tablesorter.defaults, settings);
  698.                     // store common expression for speed
  699.                     $this = $(this);
  700.                     // save the settings where they read
  701.                     $.data(this, "tablesorter", config);
  702.                     // build headers
  703.                     $headers = buildHeaders(this);
  704.                     // try to auto detect column type, and store in tables config
  705.                     this.config.parsers = buildParserCache(this, $headers);
  706.                     // build the cache for the tbody cells
  707.                     cache = buildCache(this);
  708.                     // get the css class names, could be done else where.
  709.                     var sortCSS = [config.cssDesc, config.cssAsc];
  710.                     // fixate columns if the users supplies the fixedWidth option
  711.                     fixColumnWidth(this);
  712.                     // apply event handling to headers
  713.                     // this is to big, perhaps break it out?
  714.                     $headers.click(
  715.  
  716.                     function (e) {
  717.                         var totalRows = ($this[0].tBodies[0] && $this[0].tBodies[0].rows.length) || 0;
  718.                         if (!this.sortDisabled && totalRows > 0) {
  719.                             // Only call sortStart if sorting is
  720.                             // enabled.
  721.                             $this.trigger("sortStart");
  722.                             // store exp, for speed
  723.                             var $cell = $(this);
  724.                             // get current column index
  725.                             var i = this.column;
  726.                             // get current column sort order
  727.                             this.order = this.count++ % 2;
  728.                                                         // always sort on the locked order.
  729.                                                         if(this.lockedOrder) this.order = this.lockedOrder;
  730.                                                        
  731.                                                         // user only whants to sort on one
  732.                             // column
  733.                             if (!e[config.sortMultiSortKey]) {
  734.                                 // flush the sort list
  735.                                 config.sortList = [];
  736.                                 if (config.sortForce != null) {
  737.                                     var a = config.sortForce;
  738.                                     for (var j = 0; j < a.length; j++) {
  739.                                         if (a[j][0] != i) {
  740.                                             config.sortList.push(a[j]);
  741.                                         }
  742.                                     }
  743.                                 }
  744.                                 // add column to sort list
  745.                                 config.sortList.push([i, this.order]);
  746.                                 // multi column sorting
  747.                             } else {
  748.                                 // the user has clicked on an all
  749.                                 // ready sortet column.
  750.                                 if (isValueInArray(i, config.sortList)) {
  751.                                     // revers the sorting direction
  752.                                     // for all tables.
  753.                                     for (var j = 0; j < config.sortList.length; j++) {
  754.                                         var s = config.sortList[j],
  755.                                             o = config.headerList[s[0]];
  756.                                         if (s[0] == i) {
  757.                                             o.count = s[1];
  758.                                             o.count++;
  759.                                             s[1] = o.count % 2;
  760.                                         }
  761.                                     }
  762.                                 } else {
  763.                                     // add column to sort list array
  764.                                     config.sortList.push([i, this.order]);
  765.                                 }
  766.                             };
  767.                             setTimeout(function () {
  768.                                 // set css for headers
  769.                                 setHeadersCss($this[0], $headers, config.sortList, sortCSS);
  770.                                 appendToTable(
  771.                                         $this[0], multisort(
  772.                                         $this[0], config.sortList, cache)
  773.                                                                 );
  774.                             }, 1);
  775.                             // stop normal event by returning false
  776.                             return false;
  777.                         }
  778.                         // cancel selection
  779.                     }).mousedown(function () {
  780.                         if (config.cancelSelection) {
  781.                             this.onselectstart = function () {
  782.                                 return false
  783.                             };
  784.                             return false;
  785.                         }
  786.                     });
  787.                     // apply easy methods that trigger binded events
  788.                     $this.bind("update", function () {
  789.                         var me = this;
  790.                         setTimeout(function () {
  791.                             // rebuild parsers.
  792.                             me.config.parsers = buildParserCache(
  793.                             me, $headers);
  794.                             // rebuild the cache map
  795.                             cache = buildCache(me);
  796.                         }, 1);
  797.                     }).bind("updateCell", function (e, cell) {
  798.                         var config = this.config;
  799.                         // get position from the dom.
  800.                         var pos = [(cell.parentNode.rowIndex - 1), cell.cellIndex];
  801.                         // update cache
  802.                         cache.normalized[pos[0]][pos[1]] = config.parsers[pos[1]].format(
  803.                         getElementText(config, cell), cell);
  804.                     }).bind("sorton", function (e, list) {
  805.                         $(this).trigger("sortStart");
  806.                         config.sortList = list;
  807.                         // update and store the sortlist
  808.                         var sortList = config.sortList;
  809.                         // update header count index
  810.                         updateHeaderSortCount(this, sortList);
  811.                         // set css for headers
  812.                         setHeadersCss(this, $headers, sortList, sortCSS);
  813.                         // sort the table and append it to the dom
  814.                         appendToTable(this, multisort(this, sortList, cache));
  815.                     }).bind("appendCache", function () {
  816.                         appendToTable(this, cache);
  817.                     }).bind("applyWidgetId", function (e, id) {
  818.                         getWidgetById(id).format(this);
  819.                     }).bind("applyWidgets", function () {
  820.                         // apply widgets
  821.                         applyWidget(this);
  822.                     });
  823.                     if ($.metadata && ($(this).metadata() && $(this).metadata().sortlist)) {
  824.                         config.sortList = $(this).metadata().sortlist;
  825.                     }
  826.                     // if user has supplied a sort list to constructor.
  827.                     if (config.sortList.length > 0) {
  828.                         $this.trigger("sorton", [config.sortList]);
  829.                     }
  830.                     // apply widgets
  831.                     applyWidget(this);
  832.                 });
  833.             };
  834.             this.addParser = function (parser) {
  835.                 var l = parsers.length,
  836.                     a = true;
  837.                 for (var i = 0; i < l; i++) {
  838.                     if (parsers[i].id.toLowerCase() == parser.id.toLowerCase()) {
  839.                         a = false;
  840.                     }
  841.                 }
  842.                 if (a) {
  843.                     parsers.push(parser);
  844.                 };
  845.             };
  846.             this.addWidget = function (widget) {
  847.                 widgets.push(widget);
  848.             };
  849.             this.formatFloat = function (s) {
  850.                 var i = parseFloat(s);
  851.                 return (isNaN(i)) ? 0 : i;
  852.             };
  853.             this.formatInt = function (s) {
  854.                 var i = parseInt(s);
  855.                 return (isNaN(i)) ? 0 : i;
  856.             };
  857.             this.isDigit = function (s, config) {
  858.                 // replace all an wanted chars and match.
  859.                 return /^[-+]?\d*$/.test($.trim(s.replace(/[,.']/g, '')));
  860.             };
  861.             this.clearTableBody = function (table) {
  862.                 if ($.browser.msie) {
  863.                     function empty() {
  864.                         while (this.firstChild)
  865.                         this.removeChild(this.firstChild);
  866.                     }
  867.                     empty.apply(table.tBodies[0]);
  868.                 } else {
  869.                     table.tBodies[0].innerHTML = "";
  870.                 }
  871.             };
  872.         }
  873.     });
  874.  
  875.     // extend plugin scope
  876.     $.fn.extend({
  877.         tablesorter: $.tablesorter.construct
  878.     });
  879.  
  880.     // make shortcut
  881.     var ts = $.tablesorter;
  882.  
  883.     // add default parsers
  884.     ts.addParser({
  885.         id: "text",
  886.         is: function (s) {
  887.             return true;
  888.         }, format: function (s) {
  889.             return $.trim(s.toLocaleLowerCase());
  890.         }, type: "text"
  891.     });
  892.  
  893.     ts.addParser({
  894.         id: "digit",
  895.         is: function (s, table) {
  896.             var c = table.config;
  897.             return $.tablesorter.isDigit(s, c);
  898.         }, format: function (s) {
  899.             return $.tablesorter.formatFloat(s);
  900.         }, type: "numeric"
  901.     });
  902.  
  903.     ts.addParser({
  904.         id: "currency",
  905.         is: function (s) {
  906.             return /^[Ā£$ā‚¬?.]/¬?.]/.test(s);
  907.         }, format: function (s) {
  908.             return $.tablesorter.formatFloat(s.replace(new RegExp(‚¬]/g), "")¬]/g), ""));
  909.         }, type: "numeric"
  910.     });
  911.  
  912.     ts.addParser({
  913.         id: "ipAddress",
  914.         is: function (s) {
  915.             return ]\d{2,3}[\.]\d{2,3}[\.]\d{2,3}$/.test(s);
  916.   .test(s);
  917.         }, format: function (s) {
  918.             var a = s.split("."),
  919.                 r = "",
  920.                 l = a.length;
  921.             for (var i = 0; i < l; i++) {
  922.                 var item = a[i];
  923.                 if (item.length == 2) {
  924.                     r += "0" + item;
  925.                 } else {
  926.                     r += item;
  927.                 }
  928.             }
  929.             return $.tablesorter.formatFloat(r);
  930.         }, type: "numeric"
  931.     });
  932.  
  933.     ts.addParser({
  934.         id: "url",
  935.         is: function (s) {
  936.             return p|file):\/\/$/.test(s);
  937.   .test(s);
  938.         }, format: function (s) {
  939.             return jQuery.trim(s.replace(new RegExp(|file):\/\//), ''));
  940.    ), ''));
  941.         }, type: "text"
  942.     });
  943.  
  944.     ts.addParser({
  945.         id: "isoDate",
  946.         is: function (s) {
  947.             return \d{1,2}[\/-]\d{1,2}$/.test(s);
  948.   .test(s);
  949.         }, format: function (s) {
  950.             return $.tablesorter.formatFloat((s != "") ? new Date(s.replace(
  951.             new RegExp(.get), "/")).getTime() : "0");
  952.         }, type: "numeric"
  953.     });
  954.  
  955.     ts.addParser({
  956.         id: "percent",
  957.         is: function (s) {
  958.             return .trim.test($.trim(s));
  959.         }, format: function (s) {
  960.             return $.tablesorter.formatFloat(s.replace(new RegExp(
  961.    ), ""));
  962.         }, type: "numeric"
  963.     });
  964.  
  965.     ts.addParser({
  966.         id: "usLongDate",
  967.         is: function (s) {
  968.             return s.match(new RegExp(,10}\.? [0-9]{1,2}, ([0-9]{4}|'?[0-9]{2}) (([0-2]?[0-9]:[0-5][0-9])|([0-1]?[0-9]:[0-5][0-9]\s(AM|PM)))$/));
  969.         ));
  970.         }, format: function (s) {
  971.             return $.tablesorter.formatFloat(new Date(s).getTime());
  972.         }, type: "numeric"
  973.     });
  974.  
  975.     ts.addParser({
  976.         id: "shortDate",
  977.         is: function (s) {
  978.             return -]\d{1,2}[\/\-]\d{2,4}/.test(s);
  979.   .test(s);
  980.         }, format: function (s, table) {
  981.             var c = table.config;
  982.             s = s.replace(
  983.     , "/");
  984.             if (c.dateFormat == "us") {
  985.     // reformat the string in ISO format
  986.  ISO format
  987.                 s = s.replace(/\-](\d{1,2})[\/\-](\d{4})/, "$3/$1/$2", "$3/$1/$2");
  988.             } else if (c.dateFormat == "uk") {
  989.     // reformat the string in ISO format
  990.  ISO format
  991.                 s = s.replace(/\-](\d{1,2})[\/\-](\d{4})/, "$3/$2/$1", "$3/$2/$1");
  992.             } else if (c.dateFormat == "dd/mm/yy" || c.dateFormat == "dd-mm-yy") {
  993.                 s = s.replace(/\-](\d{1,2})[\/\-](\d{2})/, "$1/$2/$3", "$1/$2/$3");
  994.             }
  995.             return $.tablesorter.formatFloat(new Date(s).getTime());
  996.         }, type: "numeric"
  997.     });
  998.     ts.addParser({
  999.         id: "time",
  1000.         is: function (s) {
  1001.             return -9]:[0-5][0-9])|([0-1]?[0-9]:[0-5][0-9]\s(am|pm)))$/.test(s);
  1002.   .test(s);
  1003.         }, format: function (s) {
  1004.             return $.tablesorter.formatFloat(new Date(" + s).getTime());
  1005.        }, type: "  }, type: "numeric"
  1006.     });
  1007.     ts.addParser({
  1008.         id: "metadata",
  1009.         is: function (s) {
  1010.             return false;
  1011.         }, format: function (s, table, cell) {
  1012.             var c = table.config,
  1013.                 p = (!c.parserMetadataName) ? 'sortValue' : c.parserMetadataName;
  1014.             return $(cell).metadata()[p];
  1015.         }, type: "numeric"
  1016. // add default widgets
  1017. ult widgets
  1018.     ts.addWidget({
  1019.         id: "zebra",
  1020.         format: function (table) {
  1021.             if (table.config.debug) {
  1022.                 var time = new Date();
  1023.             }
  1024.             var $tr, row = -1,
  1025.                 odd;
  1026. // loop through the visible rows
  1027. isible rows
  1028.             $("tr:visible", table.tBodies[0]).each(function (i) {
  1029.                 $tr = $(this);
  1030.     // style children rows the same way the parent
  1031.  the parent
  1032.     // row was styled
  1033.  was styled
  1034.                 if (!$tr.hasClass(table.config.cssChildRow)) row++;
  1035.                 odd = (row % 2 == 0);
  1036.                 $tr.removeClass(
  1037.                 table.config.widgetZebra.css[odd ? 0 : 1]).addClass(
  1038.                 table.config.widgetZebra.css[odd ? 1 : 0])
  1039.             });
  1040.             if (table.config.debug) {
  1041.                 $.tablesorter.benchmark("Applying Zebra widget", time);
  1042.             }
  1043.         }
  1044.     });

Raw Paste


Login or Register to edit or fork this paste. It's free.