From 35be6689fbef80d2381c709d108d91d1ac47e00e Mon Sep 17 00:00:00 2001 From: Mottie Date: Fri, 7 Mar 2014 12:53:21 -0600 Subject: [PATCH] cleanup & version bump --- README.md | 196 ++----- addons/pager/jquery.tablesorter.pager.js | 2 +- addons/pager/jquery.tablesorter.pager.min.js | 4 +- bower.json | 2 +- js/jquery.tablesorter.js | 7 +- js/jquery.tablesorter.min.js | 4 +- js/jquery.tablesorter.widgets.js | 2 +- js/jquery.tablesorter.widgets.min.js | 24 +- js/parsers/parser-date-two-digit-year.js | 2 +- js/widgets/widget-columnSelector.js | 8 +- js/widgets/widget-grouping.js | 6 +- js/widgets/widget-pager.js | 2 +- package.json | 2 +- tablesorter.jquery.json | 2 +- test.html | 524 ------------------- testing/testing.js | 522 ++++++++++++++++++ 16 files changed, 611 insertions(+), 698 deletions(-) diff --git a/README.md b/README.md index bc5a671a..856b31f1 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,62 @@ tablesorter can successfully parse and sort many types of data including linked View the [complete listing here](https://github.com/Mottie/tablesorter/wiki/Change). +#### Version 2.15.6 (3/7/2014) + +* Doc + * Added docs for `$.tablesorter.language` which contains the text used in the `aria-label` for the header + * Update `isValueInArray` & `sortAppend` docs. + +* Core + * Destroy now unbinds the `updateCache` method properly + * Update `$.tablesorter.isValueInArray` function & `sortAppend` option. Fixes [issue #523](https://github.com/Mottie/tablesorter/issues/523). + * All test dates are now time zone & DST independent. Fixes [issue #516](https://github.com/Mottie/tablesorter/issues/516). + * Added tests for `sortForce`, `sortAppend`, `sortMultiSortKey` and `sortResetKey`. + * Cache natural sort regex. + * Date parsers now return the original cell text instead of an empty string when encountering invalid dates. Sort of fixes [issue #531](https://github.com/Mottie/tablesorter/issues/531). + * Event fixes: + * Sort events will now only show when the table is being sorted; previously when updating an unsorted table, sort events would fire. + * The `updateComplete` event now fires after every triggered update (`update`, `updateRows`, `updateAll`, `updateCell` & `addRows`) + * Updated pager to correctly trigger the `updateComplete` event when using ajax. + * Added unit tests to ensure these events fire on an empty table. + * Fixes [issue #532](https://github.com/Mottie/tablesorter/issues/532) + +* ColumnSelector widget + * Make column disable, visible & invisible methods consistent. Fixes [issue #519](https://github.com/Mottie/tablesorter/issues/519) + +* Filter widget + * Preset filter searches (set by `data-value` on the header) work again. Fixes issues [#511](https://github.com/Mottie/tablesorter/issues/511) & [#525](https://github.com/Mottie/tablesorter/issues/525). + * Add note to docs about adding a placeholder. Fixes [issue #522](https://github.com/Mottie/tablesorter/issues/522). + * Filter build select function no longer causes a javascript error on empty tables. Fixes [issue #528](https://github.com/Mottie/tablesorter/issues/528). + +* Grouping widget + * The `collapsed` option once again shows the group headers. Fixes issues [#514](https://github.com/Mottie/tablesorter/issues/514) & [533](https://github.com/Mottie/tablesorter/issues/533) + * Add `group_saveGroups` & `group_saveReset` options: + * The `group_saveGroups` option (`true` by default) saves the group name of any collapsed groups (requires `group_collapsible` to be `true`) + * The `group_saveReset` option (`null` by default) contains a jQuery selector string or jQuery object pointing to an element to be used to clear the saved groups. + * Both of these options require the storage utility script contained within the `jquery.tablesorter.widgets.js` file. + * Fullfils feature request of [issue #514](https://github.com/Mottie/tablesorter/issues/514). + * Added details about using regular expressions within the `group_separator` option. + +* Header Titles widget (headerTitles) + * New widget which adds the current sort to the header title attribute. + * It distinguishes between a text and numeric sort and includes the current sort direction + * A prefix can be included. + * By default, an ascending sort shows either "A - Z" or "0 - 9", or "Z - A" or "9 - 0" for descending sorts. + * Note that date columns will show as numeric + * Fixes [issue #529](https://github.com/Mottie/tablesorter/issues/529). + +* Pager (addon & widget) + * Ensure empty array `[]` and array of empty strings `['', '', '']` evaluate as the same when checking if the filters have changed. Fixes [issue #202](https://github.com/Mottie/tablesorter/issues/202) (again). + * Compare `totalRows` vs. `totalPages` when preventing an ajax call. + * Changes to make the `updateComplete` event fire, but because of the asynchronous nature of ajax, it fires before any `sortEnd` events. It may take some more work to resolve this, if it becomes a concern. + * Attempted to fix pager row count issue. See [issue #455](https://github.com/Mottie/tablesorter/issues/455). + +* Miscellaneous + * Pager custom controls (beta) now shows no pages on a single page. Fixes [issue #518](https://github.com/Mottie/tablesorter/issues/518) + * Increase Bootstrap 3 theme css specificity. See [issue #515](https://github.com/Mottie/tablesorter/issues/515) + * Checkbox parser no longer causes a js error when a checkbox doesn't exist. + #### Version 2.15.5 (2/23/2014) * Pager widget now initializes properly when using ajax. Fixes [issue #510](https://github.com/Mottie/tablesorter/issues/510). @@ -77,143 +133,3 @@ View the [complete listing here](https://github.com/Mottie/tablesorter/wiki/Chan * Added `delayInit` demo ([pull #504](https://github.com/Mottie/tablesorter/issues/473)) - thanks [Infeligo](https://github.com/Infeligo)! * Fixed some markup issues & rearranged some links * Updated minified widget file date. Fixes [issue #505](https://github.com/Mottie/tablesorter/issues/505) - -#### Version 2.15.1 (2/19/2014) - -* Filter widget - * Switched method of saving last search times, as cloned table parts would not include saved data - * Fixes [issue #473](https://github.com/Mottie/tablesorter/issues/473). - -#### Version 2.15.0 (2/19/2014) - -* Core - * Add accessibility attributes to tablesorter (aria). - * Make header's `bindEvent` function public to allow easier binding to cloned table headers. - * Add an unsorted header class name option `cssNone` (empty string by default) and now all unsorted headers will have a class name of `tablesorter-headerUnSorted` applied; updated destroy method to remove header unsorted class name. - * Ensure only "updateRow" is triggered within the pager plugin to prevent issues with Proptype.js, see [issue #217](https://github.com/Mottie/tablesorter/issues/217). - * Clean up all public API functions to accept `table` as either a DOM element or a jQuery table object. - * The log will now display console errors and/or warnings based on those key words. - * Consolidated all default class names used by the plugin within `$.tablesorter.css` - these are class names that are not set by the options. - -* Docs - * Organize the examples section to make it easier to find the desired sort demo. - * Add associated tablesorter option (with link) with the appropriate examples. - * Add a "Custom parsers" section instead of lumping it in with the widgets. - * Add a "Work-in-progress" section for some beta demos. - * Add indicators to show which widgets are contained within the `jquery.tablesorter.widgets.js` file. - * Add an "API" section which gives details on how to use tablesorters available public variables & functions in both the core and widgets. - * Colorize the left border of code blocks to differentiate HTML, CSS and javascript. - * Update & consolidate jQuery UI accordion code. - * Miscellaneous demo fixes. - -* Parsers - * The "shortDate" parser now works properly with header colspans. Fixes [issue #474](https://github.com/Mottie/tablesorter/issues/474). - * The "currency" parser will now properly detect currencies which include a plus or minus sign. - * The "checkbox" parser (contained in the `parser-input-select.js` file) will now toggle a class name of `checked-#` (`#` is the column index) on the row. - * A new `parsed` parameter has been added to the parser code block. - * This parameter is set with a boolean value (i.e. `true` or `false`), to signal the filter widget to only search through parsed data when `true`. - * All parsers within the "parser-input-select.js" file now include a `parsed:true` parameter. - * The [parsers](http://mottie.github.io/tablesorter/docs/example-parsers.html) and [parsers-advanced](http://mottie.github.io/tablesorter/docs/example-parsers-advanced.html) demos have been updated to reflect this addition. - -* css Sticky headers widget: - * Add `cssStickyHeaders_zIndex` option. Fixes [issue #466](https://github.com/Mottie/tablesorter/issues/466). - * Browser will now scroll to table top after filtering. Fixes [issue #482](https://github.com/Mottie/tablesorter/issues/482). - -* Column selector widget (new!) - * This widget can make a table responsive. It uses similar parameters as those used by jQuery mobile to set priorities for hiding columns (uses "data-priority" attribute). - * The column priorities range from 1 to 6, with 1 having the highest priority. As the browser window shrinks, lower priority (higher numbers) columns will be hidden first until all numbered priority columns are hidden. - * Any named data-priority, other than the numbers 1 - 6, (e.g. "critical" or "persistent") will be treated as a column which *will not be included* in the column selector. - * With the addition of some basic selector markup and css, this widget will also allow selecting (hiding or showing) table columns. - * Popups can also be targetted for addition of these selectors; [the demo](http://mottie.github.io/tablesorter/docs/example-widget-column-selector.html) includes a Bootstrap popover sample. - * Css selectors are used to hide/show columns for optimal speed and therefore will not work in IE8 and older browsers. - * jQuery version 1.7+ and tablesorter verison 2.8+ are needed for this widget to work properly. - * Check out the [demo](http://mottie.github.io/tablesorter/docs/example-widget-column-selector.html) with more details on how to setup this widget! - -* Editable widget - * Refresh other widgets after a cell has been edited. Fixes [issue #487](https://github.com/Mottie/tablesorter/issues/487). - -* Filter widget: - * Make operator match higher priority than exact matching. Fixes [issue #465](https://github.com/Mottie/tablesorter/issues/465). - * Fix " OR " is now matched case insensitive. - * The `filter_cssFilter` option can now contain an array of class names to be applied to each filter input; added in addition to the "tablesorter-filter" class name. - * Start filter values are now preserved. Fixes [issue #452](https://github.com/Mottie/tablesorter/issues/452). - * Filter formatter demo: Update jQuery UI & stylesheet - fixes UI spinner. - * Fix child rows always visible when filtering. - * Update beta demo - [select2 external table filters demo](http://mottie.github.io/tablesorter/beta-testing/example-external-filters-using-select2.html), thanks to [mohitmayank](https://github.com/mohitmayank); see [pull request #469](https://github.com/Mottie/tablesorter/pull/469). - * Add `filter_hideEmpty` option - * Set this option to false to always show the filter row. - * By default, the filter row is completely hidden when no rows exist within the tbody (previous behavior) - * Fixes [issue #450](https://github.com/Mottie/tablesorter/issues/450) - * Rewrite filter match any column code - * Removed `filter_anyMatch` option - sorry about not deprecating this first! - * Added a `filter_external` option which is set to a jQuery selector string of inputs, outside of the table, to be used for searching table content. - * External inputs must have a `data-column="x"` attribute where `"x"` is the associated column to filter; `"x"` can also be set as `"any"` to match any column. - * All filters, internal and external, now automatically update and be used with the `$.tablesorter.getFilters` and `$.tablesorter.setFilters` functions. - * Please refer to the documentation for the [`filter_external` option](http://mottie.github.io/tablesorter/docs/index.html#widget-filter-external) for more details. - * Also check out the updated [filter widget external option](http://mottie.github.io/tablesorter/docs/example-widget-filter-any-match.html) and [filter widget external inputs](http://mottie.github.io/tablesorter/docs/example-widget-filter-external-inputs.html) demos. - * This fixes issues [#114](https://github.com/Mottie/tablesorter/issues/114), [#370](https://github.com/Mottie/tablesorter/issues/370), [#471](https://github.com/Mottie/tablesorter/issues/471) and [#490](https://github.com/Mottie/tablesorter/issues/490). - * Parsers with a `parsed: true` flag will now automatically force the filter widget to only search through parsed data instead of actual table cell data - * This is needed specifically for parsers of input, textarea and select elements. - * All parsers within the "parser-input-select.js" file have been updated with this parameter. - * This flag is essentially does the same thing as adding a class name of `filter-parsed` to the column header, or `filter: "parsed"` setting to the [`headers` option](http://mottie.github.io/tablesorter/docs/#headers). - -* Filter Formatter (Filter widget extension): - * These updated filter widget functions are not completely backward compatible with older versions of the filter widget. Please update both! - * Added `compare` & `selected` options: - * These options allow the adding of a comparison operator selector to the cell (e.g. `>`, `>=`, `<`, `<=`, etc). - * If any `cellText` is included, it is now wrapped in a label with a class name of "compare-select-label" and "compare-select-label#" (where "#" is the column index). - * The selector has a class name of "compare-select" and "compare-select#" (where "#" is the column index) - * Whichever type of input that is added to the cell is then wrapped in a div with class "compare-select-wrapper" and "compare-select-wrapper#" (where "#" is the column index). - * These class names allow styling of an individual filter to keep elements in line, or however you wish to style it. - * Filter reset now sets these filters to their default values, not an empty string. - * Updated to now properly restore saved filters. - * Added `endOfDay` option for jQuery UI Datepicker. - * When `true` search dates will include all times from the date chosen when a comparison is made of dates "less than" the set date. - * Example 1: if a table entry has a date of "Jan 14, 2014 11:23 AM" and the filter search is set to `<= 1/14/2014`, the table entry will be included in the search; the default set time would otherwise be "1/14/2014 00:00:00" and not include the entry from "11:23 AM". So, the `endOfDay` option sets the time to "23:59:59". - * Example 2: if searching for one specific date, this option will now search for all times within that day. For example, searching for `=1/20/2014`, and the results will include dates from 1/20/2014 00:00:00 to 1/20/2014 23:59:59. - * When comparing dates greater than the set date, the time will be set to midnight; so this option will not be applied. - * Example 3: in two date inputs, the `endOfDay` time is only applied to the "to" input; search for `1/20/2014 - 1/20/2014` - * This option is available in both the comparison (one input) and range (two inputs; "to" date input only) date pickers. - * Fixes [issue #325](https://github.com/Mottie/tablesorter/issues/325) and [issue #430](https://github.com/Mottie/tablesorter/issues/430). - -* Group widget: - * Attempt to fix ajax issue. See [issue #437](https://github.com/Mottie/tablesorter/issues/437). - * Combining group widget with pager should now work properly. Fixes [isse #437](https://github.com/Mottie/tablesorter/issues/437). - * The widget will now find the correct header cell when multiple thead rows are present. - -* Pager (plugin & widget): - * Fixed pager issues with empty tables - * When existing rows are removed from the table, the pager display will no properly update to show zero total rows. - * When starting from an empty table and content is added, all widgets are refreshed - * When updating the table via an update method, the filter search will now be applied properly. - * Fixes issues [#426](https://github.com/Mottie/tablesorter/issues/426) & [#455](https://github.com/Mottie/tablesorter/issues/455) - * Correct page calculation. Fixes [issue #468](https://github.com/Mottie/tablesorter/issues/468). - * Added custom storage keys. Thanks to [eire1130](https://github.com/eire1130); see [pull request #480](https://github.com/Mottie/tablesorter/pull/480) & [issue #481](https://github.com/Mottie/tablesorter/issues/481). - * Added a public show error function `$.tablesorter.showError( table, message );` - * Pass this function the table DOM element or jQuery object in `table` - * The message can either be a string with a message ("table refuses to cooperate") - * or, the message can be an HTML string of an entire table row (`'yeah, instead of showing your data... I am taking a nap'`) - * If the message is blank, all error rows are removed - * Fulfills [issue #486](https://github.com/Mottie/tablesorter/issues/486) - * Please note that this function was added to both the pager widget & pager plugin; In the next major release, this function will be separate from both, and can be included in the build. - * All theme files included a minor update with this change. - * Added accessibility attributes to the pager. - * Fix jsHint warnings. - -* Resizable widget - * Fix reported js error. - * The resizable reset function `$.tablesorter.resizableReset(table);` now accepts jQuery objects. - -* Sticky headers widget - * Select boxes work again within sticky headers. Fixes [issue #473](https://github.com/Mottie/tablesorter/issues/473). - * Browser will scroll to table top after filtering. - * This only occurs if the sticky header is active and after a filter is applied. - * Fixes [issue #482](https://github.com/Mottie/tablesorter/issues/482). - * Use core's new `bindEvents` public function to bind events to cloned sticky header. - * Fix sticky header alignment within `attachTo` elements. - -* Miscellaneous - * Update all Bootstrap demos to use the latest version (v3.0.3). Thanks [themilkman](https://github.com/themilkman)! - * Update all demo pages that use jQuery UI accordion with the newest version. Also added a clickable anchor to each accordion header. - * Consolidate default class names within `$.tablesorter.css` for the filter, resizer and stickyHeaders widgets. - * Renamed component.json to bower.json diff --git a/addons/pager/jquery.tablesorter.pager.js b/addons/pager/jquery.tablesorter.pager.js index 5b936716..2ed93735 100644 --- a/addons/pager/jquery.tablesorter.pager.js +++ b/addons/pager/jquery.tablesorter.pager.js @@ -1,6 +1,6 @@ /*! * tablesorter pager plugin - * updated 2/22/2014 (v2.15.4) + * updated 3/7/2014 (v2.15.6) */ /*jshint browser:true, jquery:true, unused:false */ ;(function($) { diff --git a/addons/pager/jquery.tablesorter.pager.min.js b/addons/pager/jquery.tablesorter.pager.min.js index 0f595b9c..c448b3af 100644 --- a/addons/pager/jquery.tablesorter.pager.min.js +++ b/addons/pager/jquery.tablesorter.pager.min.js @@ -1,2 +1,2 @@ -/* tablesorter pager plugin updated 2/22/2014 (v2.15.4) */ -;(function(h){var k=h.tablesorter;h.extend({tablesorterPager:new function(){this.defaults={container:null,ajaxUrl:null,customAjaxUrl:function(b,a){return a},ajaxObject:{dataType:"json"},processAjaxOnInit:!0,ajaxProcessing:function(b){return[0,[],null]},output:"{startRow} to {endRow} of {totalRows} rows",updateArrows:!0,page:0,size:10,savePages:!0,storageKey:"tablesorter-pager",fixedHeight:!1,countChildRows:!1,removeRows:!1,cssFirst:".first",cssPrev:".prev",cssNext:".next",cssLast:".last",cssGoto:".gotoPage", cssPageDisplay:".pagedisplay",cssPageSize:".pagesize",cssErrorRow:"tablesorter-errorRow",cssDisabled:"disabled",totalRows:0,totalPages:0,filteredRows:0,filteredPages:0,ajaxCounter:0,currentFilters:[],startRow:0,endRow:0,$size:null,last:{}};var u=this,l=function(b,a){var e=b.cssDisabled,d=!!a,f=d||0===b.page,g=Math.min(b.totalPages,b.filteredPages),d=d||b.page===g-1||0===b.totalPages;b.updateArrows&&(b.$container.find(b.cssFirst+","+b.cssPrev)[f?"addClass":"removeClass"](e).attr("aria-disabled",f), b.$container.find(b.cssNext+","+b.cssLast)[d?"addClass":"removeClass"](e).attr("aria-disabled",d))},q=function(b,a,e){var d,f,g,c=b.config;d=c.$table.hasClass("hasFilters")&&!a.ajaxUrl;g=(c.widgetOptions&&c.widgetOptions.filter_filteredRow||"filtered")+","+c.selectorRemove+(a.countChildRows?"":",."+c.cssChildRow);f=a.size||10;a.totalPages=Math.ceil(a.totalRows/f);a.filteredRows=d?c.$tbodies.eq(0).children("tr").not("."+g).length:a.totalRows;a.filteredPages=d?Math.ceil(a.filteredRows/f)||1:a.totalPages; if(0<=Math.min(a.totalPages,a.filteredPages)&&(g=a.size*a.page>a.filteredRows,a.startRow=g?1:0===a.filteredRows?0:a.size*a.page+1,a.page=g?0:a.page,a.endRow=Math.min(a.filteredRows,a.totalRows,a.size*(a.page+1)),d=a.$container.find(a.cssPageDisplay),g=(a.ajaxData&&a.ajaxData.output?a.ajaxData.output||a.output:a.output).replace(/\{page([\-+]\d+)?\}/gi,function(b,c){return a.totalPages?a.page+(c?parseInt(c,10):1):0}).replace(/\{\w+(\s*:\s*\w+)?\}/gi,function(b){b=b.replace(/[{}\s]/g,"");var c=b.split(":"), d=a.ajaxData,e=/(rows?|pages?)$/i.test(b)?0:"";return 1"+d+"";a.$goto.html(g).val(a.page+1)}l(a);a.initialized&&!1!==e&&(c.$table.trigger("pagerComplete",a),a.savePages&&k.storage&&k.storage(b,a.storageKey,{page:a.page,size:a.size}))},s=function(b,a){var e,d=b.config,f=d.$tbodies.eq(0);a.fixedHeight&& (f.find("tr.pagerSavedHeightSpacer").remove(),e=h.data(b,"pagerSavedHeight"))&&(e-=f.height(),5'))},z=function(b,a){var e=b.config.$tbodies.eq(0);e.find("tr.pagerSavedHeightSpacer").remove();h.data(b,"pagerSavedHeight",e.height());s(b,a);h.data(b,"pagerLastSize",a.size)},t=function(b,a){if(!a.ajaxUrl){var e, d=b.config,f=d.$tbodies.eq(0).children(),g=f.length,c=a.page*a.size,h=c+a.size,k=d.widgetOptions&&d.widgetOptions.filter_filteredRow||"filtered",p=0;for(e=0;e=c&&p";for(f=0;f"+d[g][f]+"";l+=""}e.processAjaxOnInit?r.$tbodies.eq(0).html(l): e.processAjaxOnInit=!0}p&&p.length===b&&(m=(c=n.hasClass("hasStickyHeaders"))?r.widgetOptions.$sticky.children("thead:first").children().children():"",y=n.find("tfoot tr:first").children(),r.$headers.filter("th").each(function(a){var b=h(this),d;b.find("."+k.css.icon).length?(d=b.find("."+k.css.icon).clone(!0),b.find(".tablesorter-header-inner").html(p[a]).append(d),c&&m.length&&(d=m.eq(a).find("."+k.css.icon).clone(!0),m.eq(a).find(".tablesorter-header-inner").html(p[a]).append(d))):(b.find(".tablesorter-header-inner").html(p[a]), c&&m.length&&m.eq(a).find(".tablesorter-header-inner").html(p[a]));y.eq(a).html(p[a])}))}r.showProcessing&&k.isProcessing(a);e.last.totalPages=e.totalPages=Math.ceil(e.totalRows/(e.size||10));e.last.currentFilters=e.currentFilters;e.last.sortList=(r.sortList||[]).join(",");q(a,e);s(a,e);n.trigger("updateCache",[function(){e.initialized&&(n.trigger("applyWidgets"),n.trigger("pagerChange",e))}])}e.initialized||(e.initialized=!0,h(a).trigger("applyWidgets").trigger("pagerInitialized",e))},G=function(b, a){var e=F(b,a),d=h(document),f,g=b.config;""!==e&&(g.showProcessing&&k.isProcessing(b,!0),d.bind("ajaxError.pager",function(c,e,f,g){B(null,b,a,e,g);d.unbind("ajaxError.pager")}),f=++a.ajaxCounter,a.ajaxObject.url=e,a.ajaxObject.success=function(c){f(a&&a.length||0))){e.page>=e.totalPages&&C(b,e);e.isDisabled=!1;e.initialized&&h(b).trigger("pagerChange",e);if(e.removeRows){g>a.length&&(g=a.length);k.clearTableBody(b);for(f=k.processTbody(b,b.config.$tbodies.eq(0),!0);da.page&&(a.page=0);a.page>g-1&&0!==g&&(a.page=g-1);if(f.page!==a.page||f.size!==a.size||f.totalPages!==a.totalPages||(f.currentFilters||[]).join(",")!==(a.currentFilters||[]).join(",")||f.sortList!==(d.sortList||[]).join(","))d.debug&&k.log("Pager changing to page "+a.page),a.last={page:a.page,size:a.size,sortList:(d.sortList||[]).join(","),totalPages:a.totalPages,currentFilters:a.currentFilters|| []},a.ajax?G(b,a):a.ajax||w(b,b.config.rowsCopy,a),h.data(b,"pagerLastPage",a.page),a.initialized&&!1!==e&&(d.$table.trigger("pageMoved",a),d.$table.trigger("applyWidgets"))}},x=function(b,a,e){e.size=a||e.size||10;e.$size.val(e.size);h.data(b,"pagerLastPage",e.page);h.data(b,"pagerLastSize",e.size);e.totalPages=Math.ceil(e.totalRows/e.size);n(b,e)},H=function(b,a){a.page=0;n(b,a)},C=function(b,a){a.page=Math.min(a.totalPages,a.filteredPages)-1;n(b,a)},I=function(b,a){a.page++;a.page>=Math.min(a.totalPages, a.filteredPages)-1&&(a.page=Math.min(a.totalPages,a.filteredPages)-1);n(b,a)},J=function(b,a){a.page--;0>=a.page&&(a.page=0);n(b,a)},E=function(b,a,e){var d,f=b.config;a.$size.add(a.$goto).removeClass(a.cssDisabled).removeAttr("disabled").attr("aria-disabled","false");a.isDisabled=!1;a.page=h.data(b,"pagerLastPage")||a.page||0;a.size=h.data(b,"pagerLastSize")||parseInt(a.$size.find("option[selected]").val(),10)||a.size||10;a.$size.val(a.size);a.totalPages=Math.ceil(Math.min(a.totalRows,a.filteredRows)/ a.size);b.id&&(d=b.id+"_pager_info",a.$container.find(a.cssPageDisplay).attr("id",d),f.$table.attr("aria-describedby",d));e&&(f.$table.trigger("updateRows"),x(b,a.size,a),A(b,a),s(b,a),f.debug&&k.log("pager enabled"))};u.appender=function(b,a){var e=b.config,d=e.pager;d.ajax||(e.rowsCopy=a,d.totalRows=d.countChildRows?e.$tbodies.eq(0).children().length:a.length,d.size=h.data(b,"pagerLastSize")||d.size||10,d.totalPages=Math.ceil(d.totalRows/d.size),w(b,a,d),q(b,d,!1))};u.construct=function(b){return this.each(function(){if(this.config&& this.hasInitialized){var a,e,d,f=this,g=f.config,c=g.pager=h.extend({},h.tablesorterPager.defaults,b),l=g.$table,m=c.$container=h(c.container).addClass("tablesorter-pager").show();g.debug&&k.log("Pager initializing");c.oldAjaxSuccess=c.oldAjaxSuccess||c.ajaxObject.success;g.appender=u.appender;k.filter&&0<=h.inArray("filter",g.widgets)&&(c.currentFilters=g.$table.data("lastSearch")||k.filter.setDefaults(f,g,g.widgetOptions)||[],k.setFilters(f,c.currentFilters,!1));c.savePages&&k.storage&&(a=k.storage(f, c.storageKey)||{},c.page=isNaN(a.page)?c.page:a.page,c.size=(isNaN(a.size)?c.size:a.size)||10,h.data(f,"pagerLastSize",c.size));l.unbind("filterStart filterEnd sortEnd disable enable destroy update updateRows updateAll addRows pageSize ".split(" ").join(".pager ")).bind("filterStart.pager",function(a,b){c.currentFilters=b;c.page=0}).bind("filterEnd.pager sortEnd.pager",function(){c.initialized&&(n(f,c,!1),q(f,c,!1),s(f,c))}).bind("disable.pager",function(a){a.stopPropagation();D(f,c)}).bind("enable.pager", function(a){a.stopPropagation();E(f,c,!0)}).bind("destroy.pager",function(a){a.stopPropagation();D(f,c);c.$container.hide();f.config.appender=null;c.initialized=!1;h(f).unbind("destroy.pager sortEnd.pager filterEnd.pager enable.pager disable.pager");k.storage&&k.storage(f,c.storageKey,"")}).bind("update.pager updateRows.pager updateAll.pager addRows.pager ",function(a){a.stopPropagation();t(f,c)}).bind("pageSize.pager",function(a,b){a.stopPropagation();x(f,parseInt(b,10)||10,c);t(f,c);q(f,c,!1);c.$size.length&& c.$size.val(c.size)}).bind("pageSet.pager",function(a,b){a.stopPropagation();c.page=(parseInt(b,10)||1)-1;c.$goto.length&&c.$goto.val(c.size);n(f,c);q(f,c,!1)});e=[c.cssFirst,c.cssPrev,c.cssNext,c.cssLast];d=[H,J,I,C];m.find(e.join(",")).attr("tabindex",0).unbind("click.pager").bind("click.pager",function(a){a.stopPropagation();var b=h(this),g=e.length;if(!b.hasClass(c.cssDisabled))for(a=0;a/.test(l)?h(l):h(''+l+"")).click(function(){h(this).remove()}).appendTo(k.$table.find("thead:first")).addClass(s+ " "+k.selectorRemove.replace(/^[.#]/,"")).attr({role:"alert","aria-live":"assertive"}))})};h.fn.extend({tablesorterPager:h.tablesorterPager.construct})})(jQuery); +/* tablesorter pager plugin updated 3/7/2014 (v2.15.6) */ +;(function(h){var k=h.tablesorter;h.extend({tablesorterPager:new function(){this.defaults={container:null,ajaxUrl:null,customAjaxUrl:function(b,a){return a},ajaxObject:{dataType:"json"},processAjaxOnInit:!0,ajaxProcessing:function(b){return[0,[],null]},output:"{startRow} to {endRow} of {totalRows} rows",updateArrows:!0,page:0,size:10,savePages:!0,storageKey:"tablesorter-pager",fixedHeight:!1,countChildRows:!1,removeRows:!1,cssFirst:".first",cssPrev:".prev",cssNext:".next",cssLast:".last",cssGoto:".gotoPage", cssPageDisplay:".pagedisplay",cssPageSize:".pagesize",cssErrorRow:"tablesorter-errorRow",cssDisabled:"disabled",totalRows:0,totalPages:0,filteredRows:0,filteredPages:0,ajaxCounter:0,currentFilters:[],startRow:0,endRow:0,$size:null,last:{}};var u=this,l=function(b,a){var d=b.cssDisabled,e=!!a,f=e||0===b.page,g=Math.min(b.totalPages,b.filteredPages),e=e||b.page===g-1||0===b.totalPages;b.updateArrows&&(b.$container.find(b.cssFirst+","+b.cssPrev)[f?"addClass":"removeClass"](d).attr("aria-disabled",f), b.$container.find(b.cssNext+","+b.cssLast)[e?"addClass":"removeClass"](d).attr("aria-disabled",e))},q=function(b,a,d){var e,f,g,c=b.config;e=c.$table.hasClass("hasFilters")&&!a.ajaxUrl;g=(c.widgetOptions&&c.widgetOptions.filter_filteredRow||"filtered")+","+c.selectorRemove+(a.countChildRows?"":",."+c.cssChildRow);f=a.size||10;a.totalPages=Math.ceil(a.totalRows/f);a.filteredRows=e?c.$tbodies.eq(0).children("tr").not("."+g).length:a.totalRows;a.filteredPages=e?Math.ceil(a.filteredRows/f)||1:a.totalPages; if(0<=Math.min(a.totalPages,a.filteredPages)&&(g=a.size*a.page>a.filteredRows,a.startRow=g?1:0===a.filteredRows?0:a.size*a.page+1,a.page=g?0:a.page,a.endRow=Math.min(a.filteredRows,a.totalRows,a.size*(a.page+1)),e=a.$container.find(a.cssPageDisplay),g=(a.ajaxData&&a.ajaxData.output?a.ajaxData.output||a.output:a.output).replace(/\{page([\-+]\d+)?\}/gi,function(c,b){return a.totalPages?a.page+(b?parseInt(b,10):1):0}).replace(/\{\w+(\s*:\s*\w+)?\}/gi,function(c){c=c.replace(/[{}\s]/g,"");var b=c.split(":"), d=a.ajaxData,e=/(rows?|pages?)$/i.test(c)?0:"";return 1"+e+"";a.$goto.html(g).val(a.page+1)}l(a);a.initialized&&!1!==d&&(c.$table.trigger("pagerComplete",a),a.savePages&&k.storage&&k.storage(b,a.storageKey,{page:a.page,size:a.size}))},s=function(b,a){var d,e=b.config,f=e.$tbodies.eq(0);a.fixedHeight&& (f.find("tr.pagerSavedHeightSpacer").remove(),d=h.data(b,"pagerSavedHeight"))&&(d-=f.height(),5'))},z=function(b,a){var d=b.config.$tbodies.eq(0);d.find("tr.pagerSavedHeightSpacer").remove();h.data(b,"pagerSavedHeight",d.height());s(b,a);h.data(b,"pagerLastSize",a.size)},t=function(b,a){if(!a.ajaxUrl){var d, e=b.config,f=e.$tbodies.eq(0).children(),g=f.length,c=a.page*a.size,h=c+a.size,k=e.widgetOptions&&e.widgetOptions.filter_filteredRow||"filtered",p=0;for(d=0;d=c&&p";for(f=0;f"+e[g][f]+"";l+=""}d.processAjaxOnInit?r.$tbodies.eq(0).html(l): d.processAjaxOnInit=!0}p&&p.length===b&&(m=(c=n.hasClass("hasStickyHeaders"))?r.widgetOptions.$sticky.children("thead:first").children().children():"",y=n.find("tfoot tr:first").children(),r.$headers.filter("th").each(function(a){var b=h(this),d;b.find("."+k.css.icon).length?(d=b.find("."+k.css.icon).clone(!0),b.find(".tablesorter-header-inner").html(p[a]).append(d),c&&m.length&&(d=m.eq(a).find("."+k.css.icon).clone(!0),m.eq(a).find(".tablesorter-header-inner").html(p[a]).append(d))):(b.find(".tablesorter-header-inner").html(p[a]), c&&m.length&&m.eq(a).find(".tablesorter-header-inner").html(p[a]));y.eq(a).html(p[a])}))}r.showProcessing&&k.isProcessing(a);d.totalPages=Math.ceil(d.totalRows/(d.size||10));d.last.totalRows=d.totalRows;d.last.currentFilters=d.currentFilters;d.last.sortList=(r.sortList||[]).join(",");q(a,d);s(a,d);n.trigger("updateCache",[function(){d.initialized&&n.trigger("applyWidgets").trigger("pagerChange",d)}])}d.initialized||(d.initialized=!0,h(a).trigger("applyWidgets").trigger("pagerInitialized",d))},G=function(b, a){var d=F(b,a),e=h(document),f,g=b.config;""!==d&&(g.showProcessing&&k.isProcessing(b,!0),e.bind("ajaxError.pager",function(c,d,f,g){B(null,b,a,d,g);e.unbind("ajaxError.pager")}),f=++a.ajaxCounter,a.ajaxObject.url=d,a.ajaxObject.success=function(c){f(a&&a.length||0))){d.page>=d.totalPages&&C(b,d);d.isDisabled=!1;d.initialized&&g.trigger("pagerChange",d);if(d.removeRows){c>a.length&&(c=a.length);k.clearTableBody(b);for(f=k.processTbody(b,f.$tbodies.eq(0),!0);ea.page&&(a.page=0);a.page>c-1&&0!==c&&(a.page=c-1);g.currentFilters=""===(g.currentFilters||[]).join("")?[]:g.currentFilters;a.currentFilters=""===(a.currentFilters||[]).join("")?[]:a.currentFilters;if(g.page!==a.page||g.size!==a.size||g.totalRows!==a.totalRows||(g.currentFilters||[]).join(",")!==(a.currentFilters||[]).join(",")||g.sortList!==(e.sortList||[]).join(","))e.debug&&k.log("Pager changing to page "+ a.page),a.last={page:a.page,size:a.size,sortList:(e.sortList||[]).join(","),totalRows:a.totalRows,currentFilters:a.currentFilters||[]},a.ajax?G(b,a):a.ajax||w(b,e.rowsCopy,a),h.data(b,"pagerLastPage",a.page),a.initialized&&!1!==d&&(f.trigger("pageMoved",a).trigger("applyWidgets"),b.isUpdating&&f.trigger("updateComplete"))}},x=function(b,a,d){d.size=a||d.size||10;d.$size.val(d.size);h.data(b,"pagerLastPage",d.page);h.data(b,"pagerLastSize",d.size);d.totalPages=Math.ceil(d.totalRows/d.size);n(b,d)}, H=function(b,a){a.page=0;n(b,a)},C=function(b,a){a.page=Math.min(a.totalPages,a.filteredPages)-1;n(b,a)},I=function(b,a){a.page++;a.page>=Math.min(a.totalPages,a.filteredPages)-1&&(a.page=Math.min(a.totalPages,a.filteredPages)-1);n(b,a)},J=function(b,a){a.page--;0>=a.page&&(a.page=0);n(b,a)},E=function(b,a,d){var e,f=b.config;a.$size.add(a.$goto).removeClass(a.cssDisabled).removeAttr("disabled").attr("aria-disabled","false");a.isDisabled=!1;a.page=h.data(b,"pagerLastPage")||a.page||0;a.size=h.data(b, "pagerLastSize")||parseInt(a.$size.find("option[selected]").val(),10)||a.size||10;a.$size.val(a.size);a.totalPages=Math.ceil(Math.min(a.totalRows,a.filteredRows)/a.size);b.id&&(e=b.id+"_pager_info",a.$container.find(a.cssPageDisplay).attr("id",e),f.$table.attr("aria-describedby",e));d&&(f.$table.trigger("updateRows"),x(b,a.size,a),A(b,a),s(b,a),f.debug&&k.log("pager enabled"))};u.appender=function(b,a){var d=b.config,e=d.pager;e.ajax||(d.rowsCopy=a,e.totalRows=e.countChildRows?d.$tbodies.eq(0).children().length: a.length,e.size=h.data(b,"pagerLastSize")||e.size||10,e.totalPages=Math.ceil(e.totalRows/e.size),w(b,a,e),q(b,e,!1))};u.construct=function(b){return this.each(function(){if(this.config&&this.hasInitialized){var a,d,e,f=this,g=f.config,c=g.pager=h.extend({},h.tablesorterPager.defaults,b),l=g.$table,m=c.$container=h(c.container).addClass("tablesorter-pager").show();g.debug&&k.log("Pager initializing");c.oldAjaxSuccess=c.oldAjaxSuccess||c.ajaxObject.success;g.appender=u.appender;k.filter&&0<=h.inArray("filter", g.widgets)&&(c.currentFilters=g.$table.data("lastSearch")||k.filter.setDefaults(f,g,g.widgetOptions)||[],k.setFilters(f,c.currentFilters,!1));c.savePages&&k.storage&&(a=k.storage(f,c.storageKey)||{},c.page=isNaN(a.page)?c.page:a.page,c.size=(isNaN(a.size)?c.size:a.size)||10,h.data(f,"pagerLastSize",c.size));l.unbind("filterStart filterEnd sortEnd disable enable destroy update updateRows updateAll addRows pageSize ".split(" ").join(".pager ")).bind("filterStart.pager",function(a,b){c.currentFilters= b;c.page=0}).bind("filterEnd.pager sortEnd.pager",function(){c.initialized&&(n(f,c,!1),q(f,c,!1),s(f,c))}).bind("disable.pager",function(a){a.stopPropagation();D(f,c)}).bind("enable.pager",function(a){a.stopPropagation();E(f,c,!0)}).bind("destroy.pager",function(a){a.stopPropagation();D(f,c);c.$container.hide();f.config.appender=null;c.initialized=!1;h(f).unbind("destroy.pager sortEnd.pager filterEnd.pager enable.pager disable.pager");k.storage&&k.storage(f,c.storageKey,"")}).bind("update.pager updateRows.pager updateAll.pager addRows.pager ", function(a){a.stopPropagation();t(f,c)}).bind("pageSize.pager",function(a,b){a.stopPropagation();x(f,parseInt(b,10)||10,c);t(f,c);q(f,c,!1);c.$size.length&&c.$size.val(c.size)}).bind("pageSet.pager",function(a,b){a.stopPropagation();c.page=(parseInt(b,10)||1)-1;c.$goto.length&&c.$goto.val(c.size);n(f,c);q(f,c,!1)});d=[c.cssFirst,c.cssPrev,c.cssNext,c.cssLast];e=[H,J,I,C];m.find(d.join(",")).attr("tabindex",0).unbind("click.pager").bind("click.pager",function(a){a.stopPropagation();var b=h(this),g= d.length;if(!b.hasClass(c.cssDisabled))for(a=0;a/.test(l)?h(l):h(''+l+"")).click(function(){h(this).remove()}).appendTo(k.$table.find("thead:first")).addClass(s+" "+k.selectorRemove.replace(/^[.#]/,"")).attr({role:"alert","aria-live":"assertive"}))})};h.fn.extend({tablesorterPager:h.tablesorterPager.construct})})(jQuery); diff --git a/bower.json b/bower.json index 20583bf6..29938704 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "tablesorter", - "version": "2.15.5", + "version": "2.15.6", "dependencies": { "jquery": ">=1.2.6" } diff --git a/js/jquery.tablesorter.js b/js/jquery.tablesorter.js index 3d393426..e11f9c68 100644 --- a/js/jquery.tablesorter.js +++ b/js/jquery.tablesorter.js @@ -1,5 +1,5 @@ /**! -* TableSorter 2.15.5 - Client-side table sorting with ease! +* TableSorter 2.15.6 - Client-side table sorting with ease! * @requires jQuery v1.2.6+ * * Copyright (c) 2007 Christian Bach @@ -24,7 +24,7 @@ var ts = this; - ts.version = "2.15.5"; + ts.version = "2.15.6"; ts.parsers = []; ts.widgets = []; @@ -756,8 +756,7 @@ } function resortComplete($table, callback){ - var table = $table[0], - c = table.config; + var table = $table[0]; if (table.isUpdating) { $table.trigger('updateComplete'); } diff --git a/js/jquery.tablesorter.min.js b/js/jquery.tablesorter.min.js index 4b04c535..7f1e1a0c 100644 --- a/js/jquery.tablesorter.min.js +++ b/js/jquery.tablesorter.min.js @@ -1,5 +1,5 @@ /*! -* TableSorter 2.15.5 min - Client-side table sorting with ease! +* TableSorter 2.15.6 min - Client-side table sorting with ease! * Copyright (c) 2007 Christian Bach */ -!function(g){g.extend({tablesorter:new function(){function d(){var a=arguments[0],b=1':"";l.$headers=g(a).find(l.selectorHeaders).each(function(a){h=g(this);c=l.headers[a];l.headerContent[a]=g(this).html();k=l.headerTemplate.replace(/\{content\}/g,g(this).html()).replace(/\{icon\}/g,w);l.onRenderTemplate&&(e=l.onRenderTemplate.apply(h,[a,k]))&&"string"===typeof e&&(k=e);g(this).html('
'+k+"
");l.onRenderHeader&&l.onRenderHeader.apply(h,[a]);this.column= b[this.parentNode.rowIndex+"-"+this.cellIndex];this.order=C(f.getData(h,c,"sortInitialOrder")||l.sortInitialOrder)?[1,0,2]:[0,1,2];this.count=-1;this.lockedOrder=!1;n=f.getData(h,c,"lockedOrder")||!1;"undefined"!==typeof n&&!1!==n&&(this.order=this.lockedOrder=C(n)?[1,1,1]:[0,0,0]);h.addClass(f.css.header+" "+l.cssHeader);l.headerList[a]=this;h.parent().addClass(f.css.headerRow+" "+l.cssHeaderRow).attr("role","row");l.tabIndex&&h.attr("tabindex",0)}).attr({scope:"col",role:"columnheader"});G(a);l.debug&& (u("Built headers:",q),d(l.$headers))}function B(a,b,c){var h=a.config;h.$table.find(h.selectorRemove).remove();s(a);v(a);H(h.$table,b,c)}function G(a){var b,c,h=a.config;h.$headers.each(function(e,d){c=g(d);b="false"===f.getData(d,h.headers[e],"sorter");d.sortDisabled=b;c[b?"addClass":"removeClass"]("sorter-false").attr("aria-disabled",""+b);a.id&&(b?c.removeAttr("aria-controls"):c.attr("aria-controls",a.id))})}function F(a){var b,c,h,e=a.config,d=e.sortList,k=f.css.sortNone+" "+e.cssNone,n=[f.css.sortAsc+ " "+e.cssAsc,f.css.sortDesc+" "+e.cssDesc],q=["ascending","descending"],l=g(a).find("tfoot tr").children().removeClass(n.join(" "));e.$headers.removeClass(n.join(" ")).addClass(k).attr("aria-sort","none");h=d.length;for(b=0;b"),c=g(a).width();g(a.tBodies[0]).find("tr:first").children("td:visible").each(function(){b.append(g("").css("width", parseInt(g(this).width()/c*1E3,10)/10+"%"))});g(a).prepend(b)}}function M(a,b){var c,h,e,f=a.config,d=b||f.sortList;f.sortList=[];g.each(d,function(a,b){c=[parseInt(b[0],10),parseInt(b[1],10)];if(e=f.$headers[c[0]])f.sortList.push(c),h=g.inArray(c[1],e.order),e.count=0<=h?h:c[1]%(f.sortReset?3:2)})}function N(a,b){return a&&a[b]?a[b].type||"":""}function O(a,b,c){var h,e,d,k=a.config,n=!c[k.sortMultiSortKey],q=g(a);q.trigger("sortStart",a);b.count=c[k.sortResetKey]?2:(b.count+1)%(k.sortReset?3:2); k.sortRestart&&(e=b,k.$headers.each(function(){this===e||!n&&g(this).is("."+f.css.sortDesc+",."+f.css.sortAsc)||(this.count=-1)}));e=b.column;if(n){k.sortList=[];if(null!==k.sortForce)for(h=k.sortForce,c=0;ch&&(k.sortList.push([e,h]),1h&&(k.sortList.push([e,h]),1 thead th, > thead td",selectorSort:"th, td",selectorRemove:".remove-me",debug:!1,headerList:[],empties:{},strings:{},parsers:[]};f.css={table:"tablesorter",childRow:"tablesorter-childRow",header:"tablesorter-header",headerRow:"tablesorter-headerRow",headerIn:"tablesorter-header-inner",icon:"tablesorter-icon",info:"tablesorter-infoOnly",processing:"tablesorter-processing", sortAsc:"tablesorter-headerAsc",sortDesc:"tablesorter-headerDesc",sortNone:"tablesorter-headerUnSorted"};f.language={sortAsc:"Ascending sort applied, ",sortDesc:"Descending sort applied, ",sortNone:"No sort applied, ",nextAsc:"activate to apply an ascending sort",nextDesc:"activate to apply a descending sort",nextNone:"activate to remove the sort"};f.log=d;f.benchmark=u;f.construct=function(a){return this.each(function(){var b=g.extend(!0,{},f.defaults,a);!this.hasInitialized&&f.buildTable&&"TABLE"!== this.tagName&&f.buildTable(this,b);f.setup(this,b)})};f.setup=function(a,b){if(!a||!a.tHead||0===a.tBodies.length||!0===a.hasInitialized)return b.debug?d("ERROR: stopping initialization! No table, thead, tbody or tablesorter has already been initialized"):"";var c="",h=g(a),e=g.metadata;a.hasInitialized=!1;a.isProcessing=!0;a.config=b;g.data(a,"tablesorter",b);b.debug&&g.data(a,"startoveralltimer",new Date);b.supportsTextContent="x"===g("x")[0].textContent;b.supportsDataObject=function(a){a[0]= parseInt(a[0],10);return 1'),c=g.fn.detach?b.detach():b.remove();c=g(a).find("span.tablesorter-savemyplace");b.insertAfter(c);c.remove();a.isProcessing=!1};f.clearTableBody=function(a){g(a)[0].config.$tbodies.empty()};f.bindEvents=function(a,b){a=g(a)[0];var c,h=a.config;b.find(h.selectorSort).add(b.filter(h.selectorSort)).unbind("mousedown.tablesorter mouseup.tablesorter sort.tablesorter keyup.tablesorter").bind("mousedown.tablesorter mouseup.tablesorter sort.tablesorter keyup.tablesorter", function(e,d){var f;f=e.type;if(!(1!==(e.which||e.button)&&!/sort|keyup/.test(f)||"keyup"===f&&13!==e.which||"mouseup"===f&&!0!==d&&250<(new Date).getTime()-c)){if("mousedown"===f)return c=(new Date).getTime(),"INPUT"===e.target.tagName?"":!h.cancelSelection;h.delayInit&&m(h.cache)&&v(a);f=/TH|TD/.test(this.tagName)?this:g(this).parents("th, td")[0];f=h.$headers[b.index(f)];f.sortDisabled||O(a,f,e)}});h.cancelSelection&&b.attr("unselectable","on").bind("selectstart",!1).css({"user-select":"none", MozUserSelect:"none"})};f.restoreHeaders=function(a){var b=g(a)[0].config;b.$table.find(b.selectorHeaders).each(function(a){g(this).find("."+f.css.headerIn).length&&g(this).html(b.headerContent[a])})};f.destroy=function(a,b,c){a=g(a)[0];if(a.hasInitialized){f.refreshWidgets(a,!0,!0);var h=g(a),e=a.config,d=h.find("thead:first"),k=d.find("tr."+f.css.headerRow).removeClass(f.css.headerRow+" "+e.cssHeaderRow),n=h.find("tfoot:first > tr").children("th, td");d.find("tr").not(k).remove();h.removeData("tablesorter").unbind("sortReset update updateAll updateRows updateCell addRows sorton appendCache applyWidgetId applyWidgets refreshWidgets destroy mouseup mouseleave keypress sortBegin sortEnd ".split(" ").join(".tablesorter ")); e.$headers.add(n).removeClass([f.css.header,e.cssHeader,e.cssAsc,e.cssDesc,f.css.sortAsc,f.css.sortDesc,f.css.sortNone].join(" ")).removeAttr("data-column");k.find(e.selectorSort).unbind("mousedown.tablesorter mouseup.tablesorter keypress.tablesorter");f.restoreHeaders(a);!1!==b&&h.removeClass(f.css.table+" "+e.tableClass+" tablesorter-"+e.theme);a.hasInitialized=!1;"function"===typeof c&&c(a)}};f.regex={chunk:/(^([+\-]?(?:0|[1-9]\d*)(?:\.\d*)?(?:[eE][+\-]?\d+)?)?$|^0x[0-9a-f]+$|\d+)/gi,hex:/^0x[0-9a-f]+$/i}; f.sortNatural=function(a,b){if(a===b)return 0;var c,h,e,d,g,n;h=f.regex;if(h.hex.test(b)){c=parseInt(a.match(h.hex),16);e=parseInt(b.match(h.hex),16);if(ce)return 1}c=a.replace(h.chunk,"\\0$1\\0").replace(/\\0$/,"").replace(/^\\0/,"").split("\\0");h=b.replace(h.chunk,"\\0$1\\0").replace(/\\0$/,"").replace(/^\\0/,"").split("\\0");n=Math.max(c.length,h.length);for(g=0;gd)return 1}return 0};f.sortNaturalAsc=function(a,b,c,d,e){if(a===b)return 0;c=e.string[e.empties[c]||e.emptyTo];return""===a&&0!==c?"boolean"===typeof c?c?-1:1:-c||-1:""===b&&0!==c?"boolean"===typeof c?c?1:-1:c||1:f.sortNatural(a,b)};f.sortNaturalDesc=function(a,b,c,d,e){if(a===b)return 0;c=e.string[e.empties[c]||e.emptyTo];return""===a&&0!==c?"boolean"===typeof c?c?-1:1:c||1:""===b&&0!==c?"boolean"===typeof c?c?1:-1:-c||-1:f.sortNatural(b, a)};f.sortText=function(a,b){return a>b?1:ag.inArray(k[h].id,m))&&(e.debug&&d('Refeshing widgets: Removing "'+k[h].id+'"'),k[h].hasOwnProperty("remove")&&e.widgetInit[k[h].id]&&(k[h].remove(a,e,e.widgetOptions),e.widgetInit[k[h].id]=!1));!0!==c&&f.applyWidget(a,b)};f.getData=function(a,b,c){var d="";a=g(a);var e,f;if(!a.length)return"";e=g.metadata?a.metadata():!1;f=" "+(a.attr("class")||"");"undefined"!==typeof a.data(c)||"undefined"!==typeof a.data(c.toLowerCase())? d+=a.data(c)||a.data(c.toLowerCase()):e&&"undefined"!==typeof e[c]?d+=e[c]:b&&"undefined"!==typeof b[c]?d+=b[c]:" "!==f&&f.match(" "+c+"-")&&(d=f.match(RegExp("\\s"+c+"-([\\w-]+)"))[1]||"");return g.trim(d)};f.formatFloat=function(a,b){if("string"!==typeof a||""===a)return a;var c;a=(b&&b.config?!1!==b.config.usNumberFormat:"undefined"!==typeof b?b:1)?a.replace(/,/g,""):a.replace(/[\s|\.]/g,"").replace(/,/g,".");/^\s*\([.\d]+\)/.test(a)&&(a=a.replace(/^\s*\(([.\d]+)\)/,"-$1"));c=parseFloat(a);return isNaN(c)? g.trim(a):c};f.isDigit=function(a){return isNaN(a)?/^[\-+(]?\d+[)]?$/.test(a.toString().replace(/[,.'"\s]/g,"")):!0}}});var p=g.tablesorter;g.fn.extend({tablesorter:p.construct});p.addParser({id:"text",is:function(){return!0},format:function(d,u){var m=u.config;d&&(d=g.trim(m.ignoreCase?d.toLocaleLowerCase():d),d=m.sortLocaleCompare?p.replaceAccents(d):d);return d},type:"text"});p.addParser({id:"digit",is:function(d){return p.isDigit(d)},format:function(d,u){var m=p.formatFloat((d||"").replace(/[^\w,. \-()]/g, ""),u);return d&&"number"===typeof m?m:d?g.trim(d&&u.config.ignoreCase?d.toLocaleLowerCase():d):d},type:"numeric"});p.addParser({id:"currency",is:function(d){return/^\(?\d+[\u00a3$\u20ac\u00a4\u00a5\u00a2?.]|[\u00a3$\u20ac\u00a4\u00a5\u00a2?.]\d+\)?$/.test((d||"").replace(/[+\-,. ]/g,""))},format:function(d,u){var m=p.formatFloat((d||"").replace(/[^\w,. \-()]/g,""),u);return d&&"number"===typeof m?m:d?g.trim(d&&u.config.ignoreCase?d.toLocaleLowerCase():d):d},type:"numeric"});p.addParser({id:"ipAddress", is:function(d){return/^\d{1,3}[\.]\d{1,3}[\.]\d{1,3}[\.]\d{1,3}$/.test(d)},format:function(d,g){var m,t=d?d.split("."):"",s="",v=t.length;for(m=0;md.length},format:function(d,g){return d?p.formatFloat(d.replace(/%/g,""),g):d},type:"numeric"});p.addParser({id:"usLongDate",is:function(d){return/^[A-Z]{3,10}\.?\s+\d{1,2},?\s+(\d{4})(\s+\d{1,2}:\d{2}(:\d{2})?(\s+[AP]M)?)?$/i.test(d)||/^\d{1,2}\s+[A-Z]{3,10}\s+\d{4}/i.test(d)},format:function(d,g){return d?p.formatFloat((new Date(d.replace(/(\S)([AP]M)$/i, "$1 $2"))).getTime()||"",g):d},type:"numeric"});p.addParser({id:"shortDate",is:function(d){return/(^\d{1,2}[\/\s]\d{1,2}[\/\s]\d{4})|(^\d{4}[\/\s]\d{1,2}[\/\s]\d{1,2})/.test((d||"").replace(/\s+/g," ").replace(/[\-.,]/g,"/"))},format:function(d,g,m,t){if(d){m=g.config;var s=m.$headers.filter("[data-column="+t+"]:last");t=s.length&&s[0].dateFormat||p.getData(s,m.headers[t],"dateFormat")||m.dateFormat;d=d.replace(/\s+/g," ").replace(/[\-.,]/g,"/");"mmddyyyy"===t?d=d.replace(/(\d{1,2})[\/\s](\d{1,2})[\/\s](\d{4})/, "$3/$1/$2"):"ddmmyyyy"===t?d=d.replace(/(\d{1,2})[\/\s](\d{1,2})[\/\s](\d{4})/,"$3/$2/$1"):"yyyymmdd"===t&&(d=d.replace(/(\d{4})[\/\s](\d{1,2})[\/\s](\d{1,2})/,"$1/$2/$3"))}return d?p.formatFloat((new Date(d)).getTime()||"",g):d},type:"numeric"});p.addParser({id:"time",is:function(d){return/^(([0-2]?\d:[0-5]\d)|([0-1]?\d:[0-5]\d\s?([AP]M)))$/i.test(d)},format:function(d,g){return d?p.formatFloat((new Date("2000/01/01 "+d.replace(/(\S)([AP]M)$/i,"$1 $2"))).getTime()||"",g):d},type:"numeric"});p.addParser({id:"metadata", is:function(){return!1},format:function(d,p,m){d=p.config;d=d.parserMetadataName?d.parserMetadataName:"sortValue";return g(m).metadata()[d]},type:"numeric"});p.addWidget({id:"zebra",priority:90,format:function(d,u,m){var t,s,v,A,D,C,E=RegExp(u.cssChildRow,"i"),B=u.$tbodies;u.debug&&(D=new Date);for(d=0;d':"";l.$headers=g(a).find(l.selectorHeaders).each(function(a){h=g(this);c=l.headers[a];l.headerContent[a]=g(this).html();k=l.headerTemplate.replace(/\{content\}/g,g(this).html()).replace(/\{icon\}/g,w);l.onRenderTemplate&&(e=l.onRenderTemplate.apply(h,[a,k]))&&"string"===typeof e&&(k=e);g(this).html('
'+k+"
");l.onRenderHeader&&l.onRenderHeader.apply(h, [a]);this.column=b[this.parentNode.rowIndex+"-"+this.cellIndex];this.order=C(f.getData(h,c,"sortInitialOrder")||l.sortInitialOrder)?[1,0,2]:[0,1,2];this.count=-1;this.lockedOrder=!1;n=f.getData(h,c,"lockedOrder")||!1;"undefined"!==typeof n&&!1!==n&&(this.order=this.lockedOrder=C(n)?[1,1,1]:[0,0,0]);h.addClass(f.css.header+" "+l.cssHeader);l.headerList[a]=this;h.parent().addClass(f.css.headerRow+" "+l.cssHeaderRow).attr("role","row");l.tabIndex&&h.attr("tabindex",0)}).attr({scope:"col",role:"columnheader"}); G(a);l.debug&&(u("Built headers:",q),d(l.$headers))}function B(a,b,c){var h=a.config;h.$table.find(h.selectorRemove).remove();s(a);v(a);H(h.$table,b,c)}function G(a){var b,c,h=a.config;h.$headers.each(function(e,d){c=g(d);b="false"===f.getData(d,h.headers[e],"sorter");d.sortDisabled=b;c[b?"addClass":"removeClass"]("sorter-false").attr("aria-disabled",""+b);a.id&&(b?c.removeAttr("aria-controls"):c.attr("aria-controls",a.id))})}function F(a){var b,c,h,e=a.config,d=e.sortList,k=f.css.sortNone+" "+e.cssNone, n=[f.css.sortAsc+" "+e.cssAsc,f.css.sortDesc+" "+e.cssDesc],q=["ascending","descending"],l=g(a).find("tfoot tr").children().removeClass(n.join(" "));e.$headers.removeClass(n.join(" ")).addClass(k).attr("aria-sort","none");h=d.length;for(b=0;b"),c=g(a).width();g(a.tBodies[0]).find("tr:first").children("td:visible").each(function(){b.append(g("").css("width", parseInt(g(this).width()/c*1E3,10)/10+"%"))});g(a).prepend(b)}}function M(a,b){var c,h,e,d=a.config,f=b||d.sortList;d.sortList=[];g.each(f,function(a,b){c=[parseInt(b[0],10),parseInt(b[1],10)];if(e=d.$headers[c[0]])d.sortList.push(c),h=g.inArray(c[1],e.order),e.count=0<=h?h:c[1]%(d.sortReset?3:2)})}function N(a,b){return a&&a[b]?a[b].type||"":""}function O(a,b,c){var h,e,d,k=a.config,n=!c[k.sortMultiSortKey],q=k.$table;q.trigger("sortStart",a);b.count=c[k.sortResetKey]?2:(b.count+1)%(k.sortReset? 3:2);k.sortRestart&&(e=b,k.$headers.each(function(){this===e||!n&&g(this).is("."+f.css.sortDesc+",."+f.css.sortAsc)||(this.count=-1)}));e=b.column;if(n){k.sortList=[];if(null!==k.sortForce)for(h=k.sortForce,c=0;ch&&(k.sortList.push([e,h]),1h&&(k.sortList.push([e,h]),1 thead th, > thead td",selectorSort:"th, td",selectorRemove:".remove-me",debug:!1,headerList:[], empties:{},strings:{},parsers:[]};f.css={table:"tablesorter",childRow:"tablesorter-childRow",header:"tablesorter-header",headerRow:"tablesorter-headerRow",headerIn:"tablesorter-header-inner",icon:"tablesorter-icon",info:"tablesorter-infoOnly",processing:"tablesorter-processing",sortAsc:"tablesorter-headerAsc",sortDesc:"tablesorter-headerDesc",sortNone:"tablesorter-headerUnSorted"};f.language={sortAsc:"Ascending sort applied, ",sortDesc:"Descending sort applied, ",sortNone:"No sort applied, ",nextAsc:"activate to apply an ascending sort", nextDesc:"activate to apply a descending sort",nextNone:"activate to remove the sort"};f.log=d;f.benchmark=u;f.construct=function(a){return this.each(function(){var b=g.extend(!0,{},f.defaults,a);!this.hasInitialized&&f.buildTable&&"TABLE"!==this.tagName&&f.buildTable(this,b);f.setup(this,b)})};f.setup=function(a,b){if(!a||!a.tHead||0===a.tBodies.length||!0===a.hasInitialized)return b.debug?d("ERROR: stopping initialization! No table, thead, tbody or tablesorter has already been initialized"):""; var c="",h=g(a),e=g.metadata;a.hasInitialized=!1;a.isProcessing=!0;a.config=b;g.data(a,"tablesorter",b);b.debug&&g.data(a,"startoveralltimer",new Date);b.supportsTextContent="x"===g("x")[0].textContent;b.supportsDataObject=function(a){a[0]=parseInt(a[0],10);return 1'), c=g.fn.detach?b.detach():b.remove();c=g(a).find("span.tablesorter-savemyplace");b.insertAfter(c);c.remove();a.isProcessing=!1};f.clearTableBody=function(a){g(a)[0].config.$tbodies.empty()};f.bindEvents=function(a,b){a=g(a)[0];var c,h=a.config;b.find(h.selectorSort).add(b.filter(h.selectorSort)).unbind("mousedown.tablesorter mouseup.tablesorter sort.tablesorter keyup.tablesorter").bind("mousedown.tablesorter mouseup.tablesorter sort.tablesorter keyup.tablesorter",function(e,d){var f;f=e.type;if(!(1!== (e.which||e.button)&&!/sort|keyup/.test(f)||"keyup"===f&&13!==e.which||"mouseup"===f&&!0!==d&&250<(new Date).getTime()-c)){if("mousedown"===f)return c=(new Date).getTime(),"INPUT"===e.target.tagName?"":!h.cancelSelection;h.delayInit&&m(h.cache)&&v(a);f=/TH|TD/.test(this.tagName)?this:g(this).parents("th, td")[0];f=h.$headers[b.index(f)];f.sortDisabled||O(a,f,e)}});h.cancelSelection&&b.attr("unselectable","on").bind("selectstart",!1).css({"user-select":"none",MozUserSelect:"none"})};f.restoreHeaders= function(a){var b=g(a)[0].config;b.$table.find(b.selectorHeaders).each(function(a){g(this).find("."+f.css.headerIn).length&&g(this).html(b.headerContent[a])})};f.destroy=function(a,b,c){a=g(a)[0];if(a.hasInitialized){f.refreshWidgets(a,!0,!0);var h=g(a),e=a.config,d=h.find("thead:first"),k=d.find("tr."+f.css.headerRow).removeClass(f.css.headerRow+" "+e.cssHeaderRow),n=h.find("tfoot:first > tr").children("th, td");d.find("tr").not(k).remove();h.removeData("tablesorter").unbind("sortReset update updateAll updateRows updateCell addRows updateComplete sorton appendCache updateCache applyWidgetId applyWidgets refreshWidgets destroy mouseup mouseleave keypress sortBegin sortEnd ".split(" ").join(".tablesorter ")); e.$headers.add(n).removeClass([f.css.header,e.cssHeader,e.cssAsc,e.cssDesc,f.css.sortAsc,f.css.sortDesc,f.css.sortNone].join(" ")).removeAttr("data-column");k.find(e.selectorSort).unbind("mousedown.tablesorter mouseup.tablesorter keypress.tablesorter");f.restoreHeaders(a);!1!==b&&h.removeClass(f.css.table+" "+e.tableClass+" tablesorter-"+e.theme);a.hasInitialized=!1;"function"===typeof c&&c(a)}};f.regex={chunk:/(^([+\-]?(?:0|[1-9]\d*)(?:\.\d*)?(?:[eE][+\-]?\d+)?)?$|^0x[0-9a-f]+$|\d+)/gi,schunk:/^\\0/, echunk:/\\0$/,hex:/^0x[0-9a-f]+$/i};f.sortNatural=function(a,b){if(a===b)return 0;var c,d,e,g,k,n;d=f.regex;if(d.hex.test(b)){c=parseInt(a.match(d.hex),16);e=parseInt(b.match(d.hex),16);if(ce)return 1}c=a.replace(d.chunk,"\\0$1\\0").replace(d.echunk,"").replace(d.schunk,"").split("\\0");d=b.replace(d.chunk,"\\0$1\\0").replace(d.echunk,"").replace(d.schunk,"").split("\\0");n=Math.max(c.length,d.length);for(k=0;kg)return 1}return 0};f.sortNaturalAsc=function(a,b,c,d,e){if(a===b)return 0;c=e.string[e.empties[c]||e.emptyTo];return""===a&&0!==c?"boolean"===typeof c?c?-1:1:-c||-1:""===b&&0!==c?"boolean"===typeof c?c?1:-1:c||1:f.sortNatural(a,b)};f.sortNaturalDesc=function(a,b,c,d,e){if(a===b)return 0;c=e.string[e.empties[c]||e.emptyTo];return""===a&&0!==c?"boolean"===typeof c?c?-1:1:c||1: ""===b&&0!==c?"boolean"===typeof c?c?1:-1:-c||-1:f.sortNatural(b,a)};f.sortText=function(a,b){return a>b?1:ag.inArray(k[h].id,m))&&(e.debug&&d('Refeshing widgets: Removing "'+k[h].id+'"'),k[h].hasOwnProperty("remove")&&e.widgetInit[k[h].id]&&(k[h].remove(a,e,e.widgetOptions),e.widgetInit[k[h].id]=!1));!0!==c&&f.applyWidget(a,b)};f.getData=function(a,b,c){var d="";a=g(a);var e,f;if(!a.length)return"";e=g.metadata?a.metadata():!1;f=" "+(a.attr("class")||"");"undefined"!== typeof a.data(c)||"undefined"!==typeof a.data(c.toLowerCase())?d+=a.data(c)||a.data(c.toLowerCase()):e&&"undefined"!==typeof e[c]?d+=e[c]:b&&"undefined"!==typeof b[c]?d+=b[c]:" "!==f&&f.match(" "+c+"-")&&(d=f.match(RegExp("\\s"+c+"-([\\w-]+)"))[1]||"");return g.trim(d)};f.formatFloat=function(a,b){if("string"!==typeof a||""===a)return a;var c;a=(b&&b.config?!1!==b.config.usNumberFormat:"undefined"!==typeof b?b:1)?a.replace(/,/g,""):a.replace(/[\s|\.]/g,"").replace(/,/g,".");/^\s*\([.\d]+\)/.test(a)&& (a=a.replace(/^\s*\(([.\d]+)\)/,"-$1"));c=parseFloat(a);return isNaN(c)?g.trim(a):c};f.isDigit=function(a){return isNaN(a)?/^[\-+(]?\d+[)]?$/.test(a.toString().replace(/[,.'"\s]/g,"")):!0}}});var p=g.tablesorter;g.fn.extend({tablesorter:p.construct});p.addParser({id:"text",is:function(){return!0},format:function(d,u){var m=u.config;d&&(d=g.trim(m.ignoreCase?d.toLocaleLowerCase():d),d=m.sortLocaleCompare?p.replaceAccents(d):d);return d},type:"text"});p.addParser({id:"digit",is:function(d){return p.isDigit(d)}, format:function(d,u){var m=p.formatFloat((d||"").replace(/[^\w,. \-()]/g,""),u);return d&&"number"===typeof m?m:d?g.trim(d&&u.config.ignoreCase?d.toLocaleLowerCase():d):d},type:"numeric"});p.addParser({id:"currency",is:function(d){return/^\(?\d+[\u00a3$\u20ac\u00a4\u00a5\u00a2?.]|[\u00a3$\u20ac\u00a4\u00a5\u00a2?.]\d+\)?$/.test((d||"").replace(/[+\-,. ]/g,""))},format:function(d,u){var m=p.formatFloat((d||"").replace(/[^\w,. \-()]/g,""),u);return d&&"number"===typeof m?m:d?g.trim(d&&u.config.ignoreCase? d.toLocaleLowerCase():d):d},type:"numeric"});p.addParser({id:"ipAddress",is:function(d){return/^\d{1,3}[\.]\d{1,3}[\.]\d{1,3}[\.]\d{1,3}$/.test(d)},format:function(d,g){var m,t=d?d.split("."):"",s="",v=t.length;for(m=0;md.length},format:function(d,g){return d?p.formatFloat(d.replace(/%/g,""),g):d},type:"numeric"});p.addParser({id:"usLongDate",is:function(d){return/^[A-Z]{3,10}\.?\s+\d{1,2},?\s+(\d{4})(\s+\d{1,2}:\d{2}(:\d{2})?(\s+[AP]M)?)?$/i.test(d)||/^\d{1,2}\s+[A-Z]{3,10}\s+\d{4}/i.test(d)},format:function(d,g){return d? p.formatFloat((new Date(d.replace(/(\S)([AP]M)$/i,"$1 $2"))).getTime()||d,g):d},type:"numeric"});p.addParser({id:"shortDate",is:function(d){return/(^\d{1,2}[\/\s]\d{1,2}[\/\s]\d{4})|(^\d{4}[\/\s]\d{1,2}[\/\s]\d{1,2})/.test((d||"").replace(/\s+/g," ").replace(/[\-.,]/g,"/"))},format:function(d,g,m,t){if(d){m=g.config;var s=m.$headers.filter("[data-column="+t+"]:last");t=s.length&&s[0].dateFormat||p.getData(s,m.headers[t],"dateFormat")||m.dateFormat;d=d.replace(/\s+/g," ").replace(/[\-.,]/g,"/");"mmddyyyy"=== t?d=d.replace(/(\d{1,2})[\/\s](\d{1,2})[\/\s](\d{4})/,"$3/$1/$2"):"ddmmyyyy"===t?d=d.replace(/(\d{1,2})[\/\s](\d{1,2})[\/\s](\d{4})/,"$3/$2/$1"):"yyyymmdd"===t&&(d=d.replace(/(\d{4})[\/\s](\d{1,2})[\/\s](\d{1,2})/,"$1/$2/$3"))}return d?p.formatFloat((new Date(d)).getTime()||d,g):d},type:"numeric"});p.addParser({id:"time",is:function(d){return/^(([0-2]?\d:[0-5]\d)|([0-1]?\d:[0-5]\d\s?([AP]M)))$/i.test(d)},format:function(d,g){return d?p.formatFloat((new Date("2000/01/01 "+d.replace(/(\S)([AP]M)$/i, "$1 $2"))).getTime()||d,g):d},type:"numeric"});p.addParser({id:"metadata",is:function(){return!1},format:function(d,p,m){d=p.config;d=d.parserMetadataName?d.parserMetadataName:"sortValue";return g(m).metadata()[d]},type:"numeric"});p.addWidget({id:"zebra",priority:90,format:function(d,u,m){var t,s,v,A,D,C,E=RegExp(u.cssChildRow,"i"),B=u.$tbodies;u.debug&&(D=new Date);for(d=0;d'),a.cssIcon&&n.find("."+c.css.icon).addClass(m.icons),q.hasClass("hasFilters")&&n.find("."+c.css.filterRow).addClass(m.filterRow));l.each(n,function(){f=l(this);h=c.css.icon?f.find("."+c.css.icon):f;this.sortDisabled?(f.removeClass(v),h.removeClass(v+" "+m.icons)):(e=f.hasClass(c.css.sortAsc)?m.sortAsc:f.hasClass(c.css.sortDesc)? m.sortDesc:f.hasClass(c.css.header)?m.sortNone:"",f[e===m.sortNone?"removeClass":"addClass"](m.active),h.removeClass(v).addClass(e))});a.debug&&c.benchmark("Applying "+p+" theme",g)},remove:function(b,a,d){b=a.$table;a=a.theme||"jui";d=c.themes[a]||c.themes.jui;var g=b.children("thead").children(),e=d.sortNone+" "+d.sortDesc+" "+d.sortAsc;b.removeClass("tablesorter-"+a+" "+d.table).find(c.css.header).removeClass(d.header);g.unbind("mouseenter.tsuitheme mouseleave.tsuitheme").removeClass(d.hover+" "+ e+" "+d.active).find("."+c.css.filterRow).removeClass(d.filterRow);g.find("."+c.css.icon).removeClass(d.icons)}}); -c.addWidget({id:"columns",priority:30,options:{columns:["primary","secondary","tertiary"]},format:function(b,a,d){var g,e,f,h,k,q,n,p,m=a.$table,v=a.$tbodies,s=a.sortList,u=s.length,w=d&&d.columns||["primary","secondary","tertiary"],x=w.length-1;n=w.join(" ");a.debug&&(g=new Date);for(f=0;f=]/g},types:{regex:function(b,a,d,g){if(c.filter.regex.regex.test(a)){var e; b=c.filter.regex.regex.exec(a);try{e=RegExp(b[1],b[2]).test(g)}catch(f){e=!1}return e}return null},operators:function(b,a,d,g,e,f,h,k,l){if(/^[<>]=?/.test(a)){var n,p;n=h.config;b=c.formatFloat(a.replace(c.filter.regex.operators,""),h);d=n.parsers[f];k=b;if(l[f]||"numeric"===d.type)n=d.format(""+a.replace(c.filter.regex.operators,""),h,n.$headers.eq(f),f),b="number"!==typeof b||""===n||isNaN(n)?b:n;n=!l[f]&&"numeric"!==d.type||isNaN(b)||!e?isNaN(g)?c.formatFloat(g.replace(c.filter.regex.nondigit, ""),h):c.formatFloat(g,h):e;/>/.test(a)&&(p=/>=/.test(a)?n>=b:n>b);/k&&(g=d,d=k,k=g);return a>=d&&a<=k||""===d||""===k}return null},wild:function(b,a,c,g,e,f,h,k,q,n){return/[\?|\*]/.test(a)||/\s+OR\s+/i.test(b)?(b=h.config,a=a.replace(/\s+OR\s+/gi,"|"),!b.$headers.filter('[data-column="'+f+'"]:last').hasClass("filter-match")&&/\|/.test(a)&&(a=l.isArray(n)?"("+a+")":"^("+a+")$"),RegExp(a.replace(/\?/g,"\\S{1}").replace(/\*/g, "\\S*")).test(g)):null},fuzzy:function(b,a,c,g){if(/^~/.test(a)){b=0;c=g.length;var e=a.slice(1);for(a=0;a'+(f.data("placeholder")||f.attr("data-placeholder")||"")+"":"",g+='");a.$table.find("thead").find("select."+c.css.filter+'[data-column="'+h+'"]').append(g)}c.filter.buildDefault(b,!0);c.filter.bindSearch(b,a.$table.find("."+c.css.filter),!0);d.filter_external&&c.filter.bindSearch(b,d.filter_external);d.filter_hideFilters&&c.filter.hideFilters(b,a);a.showProcessing&&a.$table.bind("filterStart.tsfilter filterEnd.tsfilter",function(d, e){f=e?a.$table.find("."+c.css.header).filter("[data-column]").filter(function(){return""!==e[l(this).data("column")]}):"";c.isProcessing(b,"filterStart"===d.type,e?f:"")});a.debug&&c.benchmark("Applying Filter widget",q);a.$table.bind("tablesorter-initialized pagerInitialized",function(){k=c.filter.setDefaults(b,a,d)||[];k.length&&c.setFilters(b,k,!0);a.$table.trigger("filterFomatterUpdate");c.filter.checkFilters(b,k)});d.filter_initialized=!0;a.$table.trigger("filterInit")},setDefaults:function(b, a,d){var g=c.getFilters(b);d.filter_saveFilters&&c.storage&&(d=c.storage(b,"tablesorter-filters")||[],(b=l.isArray(d))&&""===d.join("")||!b||(g=d));a.$table.data("lastSearch",g);return g},buildRow:function(b,a,d){var g,e,f,h=a.columns;e='';for(b=0;b";a.$filters=l(e+"").appendTo(a.$table.find("thead").eq(0)).find("td");for(b=0;b").appendTo(a.$filters.eq(b)):(d.filter_formatter&&l.isFunction(d.filter_formatter[b])?((e=d.filter_formatter[b](a.$filters.eq(b),b))&&0===e.length&&(e=a.$filters.eq(b).children("input")),e&&(0===e.parent().length||e.parent().length&&e.parent()[0]!==a.$filters[b])&& a.$filters.eq(b).append(e)):e=l('').appendTo(a.$filters.eq(b)),e&&e.attr("placeholder",g.data("placeholder")||g.attr("data-placeholder")||"")),e&&(g=(l.isArray(d.filter_cssFilter)?"undefined"!==typeof d.filter_cssFilter[b]?d.filter_cssFilter[b]||"":"":d.filter_cssFilter)||"",e.addClass(c.css.filter+" "+g).attr("data-column",b),f&&(e.addClass("disabled")[0].disabled=!0))},bindSearch:function(b,a,d){b=l(b)[0];a=l(a);if(a.length){var g=b.config,e=g.widgetOptions,f=e.filter_$externalFilters; !0!==d&&(e.filter_$anyMatch=a.filter('[data-column="all"]'),e.filter_$externalFilters=f&&f.length?e.filter_$externalFilters.add(a):a,c.setFilters(b,g.$table.data("lastSearch")||[],!1===d));a.attr("data-lastSearchTime",(new Date).getTime()).unbind("keyup search change").bind("keyup search change",function(a,d){l(this).attr("data-lastSearchTime",(new Date).getTime());if(27===a.which)this.value="";else if("number"===typeof e.filter_liveSearch&&this.value.lengtha.which&&8!==a.which&&!0===e.filter_liveSearch&&13!==a.which||37<=a.which&&40>=a.which||13!==a.which&&!1===e.filter_liveSearch))return;c.filter.searching(b,"",!0)});g.$table.bind("filterReset",function(){a.val("")})}},checkFilters:function(b,a,d){var g=b.config,e=g.widgetOptions,f=l.isArray(a),h=f?a:c.getFilters(b,!0),k=(h||[]).join("");f&&c.setFilters(b,h,!1,!0!==d);e.filter_hideFilters&&g.$table.find("."+c.css.filterRow).trigger(""===k?"mouseleave":"mouseenter");if(g.lastCombinedFilter!== k||!1===a)if(!1===a&&(g.lastCombinedFilter=null),g.$table.trigger("filterStart",[h]),g.showProcessing)setTimeout(function(){c.filter.findRows(b,h,k);return!1},30);else return c.filter.findRows(b,h,k),!1},hideFilters:function(b,a){var d,g,e;a.$table.find("."+c.css.filterRow).addClass("hideme").bind("mouseenter mouseleave",function(b){d=l(this);clearTimeout(e);e=setTimeout(function(){/enter|over/.test(b.type)?d.removeClass("hideme"):l(document.activeElement).closest("tr")[0]!==d[0]&&""===a.lastCombinedFilter&& d.addClass("hideme")},200)}).find("input, select").bind("focus blur",function(a){g=l(this).closest("tr");clearTimeout(e);e=setTimeout(function(){if(""===c.getFilters(b).join(""))g["focus"===a.type?"removeClass":"addClass"]("hideme")},200)})},findRows:function(b,a,d){if(b.config.lastCombinedFilter!==d){var g,e,f,h,k,q,n,p,m,v,s,u,w,x,B,z,y,D,C,A,L,E,G,H,I,J,M,r=b.config,t=r.widgetOptions,N=r.columns,K=r.$tbodies,O=["range","notMatch","operators"],F=r.$headers.map(function(a){return r.parsers&&r.parsers[a]&& r.parsers[a].parsed||(c.getData?"parsed"===c.getData(r.$headers.filter('[data-column="'+a+'"]:last'),r.headers[a],"filter"):l(this).hasClass("filter-parsed"))}).get();r.debug&&(L=new Date);for(q=0;ql.inArray(a,O)&&(z=c(E,G,I,J,M,N,b,t,F,H),null!==z))return C=z,!1}),A=null!==C?C:0<=(J+s).indexOf(G)); for(m=0;m'+(p.data("placeholder")||p.attr("data-placeholder")||"")+"";for(f=0;f"+n[g]+"":"";k=(k.$filters?k.$filters:k.$table.children("thead")).find("."+c.css.filter);b.filter_$externalFilters&&(k=k&&k.length?k.add(b.filter_$externalFilters):b.filter_$externalFilters);k.filter('select[data-column="'+ a+'"]')[d?"html":"append"](m)},buildDefault:function(b,a){var d,g,e=b.config,f=e.widgetOptions,h=e.columns;for(d=0;db.top&&cMath.abs(q.parent().width()-q.width()),s=function(){c.storage&&p&&m&&(k={},k[p.index()]=p.width(),k[m.index()]= m.width(),p.width(k[p.index()]),m.width(k[m.index()]),!1!==d.resizable&&c.storage(b,"tablesorter-resizable",k));n=0;p=m=null;l(window).trigger("resize")};if(k=c.storage&&!1!==d.resizable?c.storage(b,"tablesorter-resizable"):{})for(h in k)!isNaN(h)&&h');d.resizable_addLastColumn||(f=f.slice(0,-1));e=e?e.add(f):f});e.each(function(){var a=l(this),b=parseInt(a.css("padding-right"),10)+10;a.find("."+c.css.wrapper).append('
')}).bind("mousemove.tsresize",function(a){if(0!==n&&p){var b=a.pageX-n,c=p.width();p.width(c+b);p.width()!==c&&v&&m.width(m.width()-b);n=a.pageX}}).bind("mouseup.tsresize",function(){s()}).find("."+c.css.resizer+",."+c.css.grip).bind("mousedown",function(b){p=l(b.target).closest("th");var c=a.$headers.filter('[data-column="'+p.attr("data-column")+'"]');1'),a.cssIcon&&n.find("."+c.css.icon).addClass(m.icons),q.hasClass("hasFilters")&&n.find("."+c.css.filterRow).addClass(m.filterRow));l.each(n,function(){f=l(this);h=c.css.icon?f.find("."+c.css.icon):f;this.sortDisabled?(f.removeClass(v),h.removeClass(v+" "+m.icons)):(d=f.hasClass(c.css.sortAsc)?m.sortAsc:f.hasClass(c.css.sortDesc)? m.sortDesc:f.hasClass(c.css.header)?m.sortNone:"",f[d===m.sortNone?"removeClass":"addClass"](m.active),h.removeClass(v).addClass(d))});a.debug&&c.benchmark("Applying "+p+" theme",g)},remove:function(b,a,e){b=a.$table;a=a.theme||"jui";e=c.themes[a]||c.themes.jui;var g=b.children("thead").children(),d=e.sortNone+" "+e.sortDesc+" "+e.sortAsc;b.removeClass("tablesorter-"+a+" "+e.table).find(c.css.header).removeClass(e.header);g.unbind("mouseenter.tsuitheme mouseleave.tsuitheme").removeClass(e.hover+" "+ d+" "+e.active).find("."+c.css.filterRow).removeClass(e.filterRow);g.find("."+c.css.icon).removeClass(e.icons)}}); +c.addWidget({id:"columns",priority:30,options:{columns:["primary","secondary","tertiary"]},format:function(b,a,e){var g,d,f,h,k,q,n,p,m=a.$table,v=a.$tbodies,s=a.sortList,u=s.length,w=e&&e.columns||["primary","secondary","tertiary"],x=w.length-1;n=w.join(" ");a.debug&&(g=new Date);for(f=0;f=]/g},types:{regex:function(b,a,e,g){if(c.filter.regex.regex.test(a)){var d; b=c.filter.regex.regex.exec(a);try{d=RegExp(b[1],b[2]).test(g)}catch(f){d=!1}return d}return null},operators:function(b,a,e,g,d,f,h,k,l){if(/^[<>]=?/.test(a)){var n,p;n=h.config;b=c.formatFloat(a.replace(c.filter.regex.operators,""),h);e=n.parsers[f];k=b;if(l[f]||"numeric"===e.type)n=e.format(""+a.replace(c.filter.regex.operators,""),h,n.$headers.eq(f),f),b="number"!==typeof b||""===n||isNaN(n)?b:n;n=!l[f]&&"numeric"!==e.type||isNaN(b)||!d?isNaN(g)?c.formatFloat(g.replace(c.filter.regex.nondigit, ""),h):c.formatFloat(g,h):d;/>/.test(a)&&(p=/>=/.test(a)?n>=b:n>b);/k&&(g=e,e=k,k=g);return a>=e&&a<=k||""===e||""===k}return null},wild:function(b,a,c,g,d,f,h,k,q,n){return/[\?|\*]/.test(a)||/\s+OR\s+/i.test(b)?(b=h.config,a=a.replace(/\s+OR\s+/gi,"|"),!b.$headers.filter('[data-column="'+f+'"]:last').hasClass("filter-match")&&/\|/.test(a)&&(a=l.isArray(n)?"("+a+")":"^("+a+")$"),RegExp(a.replace(/\?/g,"\\S{1}").replace(/\*/g, "\\S*")).test(g)):null},fuzzy:function(b,a,c,g){if(/^~/.test(a)){b=0;c=g.length;var d=a.slice(1);for(a=0;a'+(f.data("placeholder")||f.attr("data-placeholder")||"")+"":"",g+='");a.$table.find("thead").find("select."+c.css.filter+'[data-column="'+h+'"]').append(g)}c.filter.buildDefault(b,!0);c.filter.bindSearch(b,a.$table.find("."+c.css.filter),!0);e.filter_external&&c.filter.bindSearch(b,e.filter_external);e.filter_hideFilters&&c.filter.hideFilters(b,a);a.showProcessing&&a.$table.bind("filterStart.tsfilter filterEnd.tsfilter",function(d, e){f=e?a.$table.find("."+c.css.header).filter("[data-column]").filter(function(){return""!==e[l(this).data("column")]}):"";c.isProcessing(b,"filterStart"===d.type,e?f:"")});a.debug&&c.benchmark("Applying Filter widget",q);a.$table.bind("tablesorter-initialized pagerInitialized",function(){k=c.filter.setDefaults(b,a,e)||[];k.length&&c.setFilters(b,k,!0);a.$table.trigger("filterFomatterUpdate");c.filter.checkFilters(b,k)});e.filter_initialized=!0;a.$table.trigger("filterInit")},setDefaults:function(b, a,e){var g,d=c.getFilters(b)||[];e.filter_saveFilters&&c.storage&&(g=c.storage(b,"tablesorter-filters")||[],(b=l.isArray(g))&&""===g.join("")||!b||(d=g));if(""===d.join(""))for(b=0;b';for(b=0;b";a.$filters=l(d+"").appendTo(a.$table.find("thead").eq(0)).find("td"); for(b=0;b").appendTo(a.$filters.eq(b)):(e.filter_formatter&&l.isFunction(e.filter_formatter[b])?((d=e.filter_formatter[b](a.$filters.eq(b),b))&&0=== d.length&&(d=a.$filters.eq(b).children("input")),d&&(0===d.parent().length||d.parent().length&&d.parent()[0]!==a.$filters[b])&&a.$filters.eq(b).append(d)):d=l('').appendTo(a.$filters.eq(b)),d&&d.attr("placeholder",g.data("placeholder")||g.attr("data-placeholder")||"")),d&&(g=(l.isArray(e.filter_cssFilter)?"undefined"!==typeof e.filter_cssFilter[b]?e.filter_cssFilter[b]||"":"":e.filter_cssFilter)||"",d.addClass(c.css.filter+" "+g).attr("data-column",b),f&&(d.addClass("disabled")[0].disabled= !0))},bindSearch:function(b,a,e){b=l(b)[0];a=l(a);if(a.length){var g=b.config,d=g.widgetOptions,f=d.filter_$externalFilters;!0!==e&&(d.filter_$anyMatch=a.filter('[data-column="all"]'),d.filter_$externalFilters=f&&f.length?d.filter_$externalFilters.add(a):a,c.setFilters(b,g.$table.data("lastSearch")||[],!1===e));a.attr("data-lastSearchTime",(new Date).getTime()).unbind("keyup search change").bind("keyup search change",function(a,e){l(this).attr("data-lastSearchTime",(new Date).getTime());if(27===a.which)this.value= "";else if("number"===typeof d.filter_liveSearch&&this.value.lengtha.which&&8!==a.which&&!0===d.filter_liveSearch&&13!==a.which||37<=a.which&&40>=a.which||13!==a.which&&!1===d.filter_liveSearch))return;c.filter.searching(b,"",!0)});g.$table.bind("filterReset",function(){a.val("")})}},checkFilters:function(b,a,e){var g=b.config,d=g.widgetOptions,f=l.isArray(a),h=f?a:c.getFilters(b,!0),k=(h||[]).join("");f&&c.setFilters(b,h,!1,!0!==e);d.filter_hideFilters&& g.$table.find("."+c.css.filterRow).trigger(""===k?"mouseleave":"mouseenter");if(g.lastCombinedFilter!==k||!1===a)if(!1===a&&(g.lastCombinedFilter=null),g.$table.trigger("filterStart",[h]),g.showProcessing)setTimeout(function(){c.filter.findRows(b,h,k);return!1},30);else return c.filter.findRows(b,h,k),!1},hideFilters:function(b,a){var e,g,d;a.$table.find("."+c.css.filterRow).addClass("hideme").bind("mouseenter mouseleave",function(b){e=l(this);clearTimeout(d);d=setTimeout(function(){/enter|over/.test(b.type)? e.removeClass("hideme"):l(document.activeElement).closest("tr")[0]!==e[0]&&""===a.lastCombinedFilter&&e.addClass("hideme")},200)}).find("input, select").bind("focus blur",function(a){g=l(this).closest("tr");clearTimeout(d);d=setTimeout(function(){if(""===c.getFilters(b).join(""))g["focus"===a.type?"removeClass":"addClass"]("hideme")},200)})},findRows:function(b,a,e){if(b.config.lastCombinedFilter!==e){var g,d,f,h,k,q,n,p,m,v,s,u,w,x,B,z,y,D,C,A,L,E,G,H,I,J,M,r=b.config,t=r.widgetOptions,N=r.columns, K=r.$tbodies,O=["range","notMatch","operators"],F=r.$headers.map(function(a){return r.parsers&&r.parsers[a]&&r.parsers[a].parsed||(c.getData?"parsed"===c.getData(r.$headers.filter('[data-column="'+a+'"]:last'),r.headers[a],"filter"):l(this).hasClass("filter-parsed"))}).get();r.debug&&(L=new Date);for(q=0;ql.inArray(a,O)&&(z=c(E,G,I,J,M,N,b,t,F,H),null!==z))return C=z, !1}),A=null!==C?C:0<=(J+s).indexOf(G));for(m=0;m'+(p.data("placeholder")||p.attr("data-placeholder")||"")+"";for(f=0;f"+n[g]+"":"";k=(k.$filters?k.$filters:k.$table.children("thead")).find("."+c.css.filter);b.filter_$externalFilters&& (k=k&&k.length?k.add(b.filter_$externalFilters):b.filter_$externalFilters);k.filter('select[data-column="'+a+'"]')[e?"html":"append"](m)}},buildDefault:function(b,a){var e,g,d=b.config,f=d.widgetOptions,h=d.columns;for(e=0;eb.top&&cMath.abs(q.parent().width()-q.width()),s=function(){c.storage&&p&&m&&(k={},k[p.index()]= p.width(),k[m.index()]=m.width(),p.width(k[p.index()]),m.width(k[m.index()]),!1!==e.resizable&&c.storage(b,"tablesorter-resizable",k));n=0;p=m=null;l(window).trigger("resize")};if(k=c.storage&&!1!==e.resizable?c.storage(b,"tablesorter-resizable"):{})for(h in k)!isNaN(h)&&h');e.resizable_addLastColumn||(f=f.slice(0,-1));d=d?d.add(f):f});d.each(function(){var a=l(this),b=parseInt(a.css("padding-right"),10)+10;a.find("."+c.css.wrapper).append('
')}).bind("mousemove.tsresize",function(a){if(0!==n&&p){var b=a.pageX-n,c=p.width();p.width(c+b);p.width()!==c&&v&&m.width(m.width()-b);n=a.pageX}}).bind("mouseup.tsresize",function(){s()}).find("."+c.css.resizer+",."+c.css.grip).bind("mousedown",function(b){p=l(b.target).closest("th");var c=a.$headers.filter('[data-column="'+p.attr("data-column")+'"]');1 -1; + isHidden = $.inArray( name, wo.group_currentGroups[wo.group_currentGroup] ) > -1; $row.toggleClass('collapsed', isHidden); $rows.toggleClass('group-hidden', isHidden); } else if (wo.group_collapsed && wo.group_collapsible) { diff --git a/js/widgets/widget-pager.js b/js/widgets/widget-pager.js index d3a9d26e..4730a3b2 100644 --- a/js/widgets/widget-pager.js +++ b/js/widgets/widget-pager.js @@ -1,4 +1,4 @@ -/* Pager widget (beta) for TableSorter 2/23/2014 (v2.15.5) */ +/* Pager widget (beta) for TableSorter 3/7/2014 (v2.15.6) */ /*jshint browser:true, jquery:true, unused:false */ ;(function($){ "use strict"; diff --git a/package.json b/package.json index a1233c1d..473c7cff 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "tablesorter", "title": "tablesorter", - "version": "2.15.5", + "version": "2.15.6", "description": "tablesorter is a jQuery plugin for turning a standard HTML table with THEAD and TBODY tags into a sortable table without page refreshes. tablesorter can successfully parse and sort many types of data including linked data in a cell.\n\nThis forked version adds lots of new enhancements including: alphanumeric sorting, pager callback functons, multiple widgets providing column styling, ui theme application, sticky headers, column filters and resizer, as well as extended documentation with a lot more demos.", "author": { "name": "Christian Bach", diff --git a/tablesorter.jquery.json b/tablesorter.jquery.json index a1233c1d..473c7cff 100644 --- a/tablesorter.jquery.json +++ b/tablesorter.jquery.json @@ -1,7 +1,7 @@ { "name": "tablesorter", "title": "tablesorter", - "version": "2.15.5", + "version": "2.15.6", "description": "tablesorter is a jQuery plugin for turning a standard HTML table with THEAD and TBODY tags into a sortable table without page refreshes. tablesorter can successfully parse and sort many types of data including linked data in a cell.\n\nThis forked version adds lots of new enhancements including: alphanumeric sorting, pager callback functons, multiple widgets providing column styling, ui theme application, sticky headers, column filters and resizer, as well as extended documentation with a lot more demos.", "author": { "name": "Christian Bach", diff --git a/test.html b/test.html index 63936eff..9458a07e 100644 --- a/test.html +++ b/test.html @@ -15,530 +15,6 @@ - -
diff --git a/testing/testing.js b/testing/testing.js index 9c2988ad..3ae48af3 100644 --- a/testing/testing.js +++ b/testing/testing.js @@ -87,3 +87,525 @@ var tester = { } }; + +/* +Core plugin tested +======================== +OPTIONS: + cssAsc, cssChildRow, cssDesc, cssHeader, cssHeaderRow, cssInfoBlock, dateFormat, emptyTo, headerList, + headers, ignoreCase, initialized, parsers, sortList, sortLocaleCompare, sortReset, stringTo, tableClass, + usNumberFormat, widgets (just zebra), sortAppend, sortForce, sortMultiSortKey, sortResetKey + +METHODS: + addRows, applyWidgets, destroy, sorton, sortReset, update/updateRow, updateAll, updateCell + +EVENTS: + initialized, sortBegin, sortEnd, sortStart, updateComplete + +Not yet tested +========================= +OPTIONS: + cancelSelection, cssIcon, cssProcessing, debug, delayInit, headerTemplate, initWidgets, onRenderHeader, + onRenderTemplate, selectorHeaders, selectorRemove, selectorSort, serverSideSorting, showProcessing, + sortInitialOrder, sortRestart, strings, + textExtraction, textSorter, theme, widthFixed, widgets (also need priority testing) + +METHODS: + appendCache, applyWidgetId, sort, refreshWidgets + +EVENTS: + - +*/ + +$(function(){ + // keep stuff in order; yeah I know every test needs to be atomic - bleh + QUnit.config.reorder = false; + + var ts = $.tablesorter, + $table1 = $('.tester:eq(0)'), + $table2 = $('.tester:eq(1)'), + $table3 = $('.tester:eq(2)'), + $table4 = $('.tester:eq(3)'), + $table5 = $('.tester:eq(4)'), // empty table + table1 = $table1[0], + table2 = $table2[0], + table3 = $table3[0], + table4 = $table4[0], + th0 = $table1.find('th')[0], // first table header cell + init = false, + sortIndx = 0, + updateIndx = 0, + updateCallback = 0, + events = ['sortStart', 'sortBegin', 'sortEnd' ], + returnTime = function(string){ + return new Date(string).getTime(); + }, + undef, c1, c2, c3, c4, e, i, l, t; + + $table1 + .bind('tablesorter-initialized', function(){ + init = true; + }) + .bind( events.join(' '), function(e){ + if (e.type === events[sortIndx%3]) { + sortIndx++; + } + }) + .bind('updateComplete', function(){ + updateIndx++; + }) + .tablesorter(); + + $table2.tablesorter({ + headers: { + 0: { sorter: 'text' }, + 1: { sorter: 'text' }, + 2: { sorter: false } + } + }); + + $table3.tablesorter({ + emptyTo: "bottom", + stringTo: "max", // non-numeric content is treated as a MAX value + headers: { + 0: { empty : "top" }, // sort empty cells to the top + 2: { string: "min" }, // non-numeric content is treated as a MIN value + 3: { sorter: "digit", empty : "zero", string : "top" } + } + }); + + $table4.tablesorter({ + sortAppend : [[2,0],[3,0]], + sortForce : [[0,0],[1,0]], + initialized: function(table){ + var e, c = table.config; + // trigger sort on 5th column + // this method is used because triggering a "sorton" would ignore sortForce/sortAppend + c.$headers.eq(4).trigger('sort'); + e = $.Event('sort'); + e.which = 1; + e.shiftKey = true; + c.$headers.eq(5).trigger(e); + } + }); + + $table5 + .bind( events.join(' '), function(e){ + if (e.type === events[sortIndx%3]) { + sortIndx++; + } + }) + .bind('updateComplete', function(){ + updateIndx++; + }) + .tablesorter(); + + // ensure all sort events fire on an empty table + $table5.trigger('sorton', [ [[0,0]] ]); + + /************************************************ + JSHint testing + ************************************************/ + // Run JSHint on main js files + tester.jsHintTest('JSHint core', 'js/jquery.tablesorter.js'); + tester.jsHintTest('JSHint pager', 'addons/pager/jquery.tablesorter.pager.js'); + tester.jsHintTest('JSHint widgets', 'js/jquery.tablesorter.widgets.js'); + tester.jsHintTest('JSHint group widget', 'js/widgets/widget-grouping.js'); + tester.jsHintTest('JSHint scroller widget', 'js/widgets/widget-scroller.js'); + + /************************************************ + Initialization + ************************************************/ + test( "tablesorter loaded & initialized", function() { + expect(3); + equal( typeof ts, 'object', "tablesorter loaded"); + equal( table1.hasInitialized, true, "tablesorter initialized flag"); + equal( init, true, "tablesorter initialized event"); + }); + + c1 = table1.config; + c2 = table2.config; + c3 = table3.config; + c4 = table4.config; + + /************************************************ + check isDigit function + ************************************************/ + var d = ts.isDigit; + test( "isDigit", function() { + expect(17); + ok( d('-1'), "allow negative (-1)"); + ok( d('+1'), "allow plus (+1)"); + ok( d('(1)'), "allow parenthesis (1)"); + ok( d('123'), "string has numbers ('123')"); + ok( d(123), "has numbers (123)"); + ok( d('1.2'), "remove decimal (1.2)"); + ok( d('1,234'),"remove commas (1,234)"); + ok( d("11'"), "remove apostrophe's (11')"); // 11 feet + ok( d('3\'4"'),"remove quotes (3'4\")"); // 3 foot 4 inches + ok( d(' 12 '), "remove spaces ( 12 )"); + ok( !d('x'), "non-digit alphabet"); + ok( !d('1x'), "digit + alphabet"); + ok( !d('x1'), "alphabet + digit"); + ok( !d('@'), "non-digit symbols"); + ok( !d('1-'), "negative after (1-) not allowed?"); + ok( !d('1+'), "plus after (1+) not allowed?"); + ok( !d('$2'), "no money; the currency parser will catch these"); + }); + + /************************************************ + check formatFloat function + ************************************************/ + var ff = function(str) { + return ts.formatFloat(str, table1); + }; + test( "formatFloat", function() { + expect(18); + strictEqual( ff(''), '', 'returns empty string' ); + strictEqual( ff(5), 5, 'returns numerical values'); + + c1.usNumberFormat = false; + strictEqual( ts.formatFloat('1,234,567.89'), 1234567.89, 'use format float without including table - defaults to US number format'); + + strictEqual( ff('1 234,56'), 1234.56, 'parse non-U.S. (French) number format'); + strictEqual( ff('1.234,56'), 1234.56, 'parse non-U.S. (German) number format'); + strictEqual( ff('-32,32'), -32.32, 'negative non-U.S. signed numbers'); + strictEqual( ff('-1.234,56'), -1234.56, 'negative non-U.S. signed numbers'); + strictEqual( ff('(32,32)'), -32.32, 'parenthesis wrapped non-U.S. negative number'); + strictEqual( ff(' (32,32) '), -32.32, 'space + parenthesis wrapped non-U.S. negative number'); + + c1.usNumberFormat = true; + strictEqual( ff('1,234.56'), 1234.56, 'parse U.S. number format'); + strictEqual( ff('-32.32'), -32.32, 'negative U.S. signed numbers'); + strictEqual( ff('(32.32)'), -32.32, 'parenthesis wrapped U.S. negative number'); + strictEqual( ff(' (32.32)'), -32.32, 'space + parenthesis wrapped U.S. negative number'); + + strictEqual( ff('fred'), 'fred', 'return string if not a number'); + strictEqual( ff(' fred '), 'fred', 'return trimmed string if not a number'); + strictEqual( ff('fred 12'), 'fred 12', 'return string if number not at beginning'); + strictEqual( ff('12fred'), 12, 'parse number + string into number only'); + strictEqual( ff('(fred)'), '(fred)', 'leave parenthesis intact on strings'); + + }); + + /************************************************ + get data function - jQuery data > meta > headers option > header class name + ************************************************/ + var gd = function(n){ + return ts.getData( c2.$headers[n], c2.headers[n], 'sorter' ); + }; + + test( "getData", function() { + expect(4); + var txt = [ 'jQuery data', 'meta data', 'headers option', 'header class name' ]; + for (i = 0; i < 4; i++) { + equal( gd(i), 'false', txt[i]); // all columns have sorter false set + } + }); + + /************************************************ + character equivalent replacement + ************************************************/ + test( "replace accents", function() { + expect(6); + strictEqual( ts.replaceAccents('\u00e1\u00e0\u00e2\u00e3\u00e4\u0105\u00e5\u00c1\u00c0\u00c2\u00c3\u00c4\u0104\u00c5'), 'aaaaaaaAAAAAAA', "replaced a's"); + strictEqual( ts.replaceAccents('\u00e9\u00e8\u00ea\u00eb\u011b\u0119\u00c9\u00c8\u00ca\u00cb\u011a\u0118'), 'eeeeeeEEEEEE', "replaced e's"); + strictEqual( ts.replaceAccents('\u00ed\u00ec\u0130\u00ee\u00ef\u0131\u00cd\u00cc\u0130\u00ce\u00cf'), 'iiiiiiIIiII', "replaced i's"); + strictEqual( ts.replaceAccents('\u00f3\u00f2\u00f4\u00f5\u00f6\u00d3\u00d2\u00d4\u00d5\u00d6'), 'oooooOOOOO', "replaced o's"); + strictEqual( ts.replaceAccents('\u00fa\u00f9\u00fb\u00fc\u016f\u00da\u00d9\u00db\u00dc\u016e'), 'uuuuuUUUUU', "replaced u's"); + strictEqual( ts.replaceAccents('\u00e7\u0107\u010d\u00c7\u0106\u010c\u00df\u1e9e'), 'cccCCCssSS', "replaced c & s sharp"); + }); + + /************************************************ + check all default parsers + ************************************************/ + var p = ts.parsers, + // test by parser + parserTests = 85, + // skipping metadata parser + sample1 = { + 'text' : { 'test': 'test', 'TesT': 'test', '\u00e1 test': '\u00e1 test' }, + 'currency' : { '\u00a31': 1, '($2.23)': -2.23, '5\u20ac': 5, '(11\u00a4)': -11, '500\u00a5': 500, '25\u00a2': 25, '$1,000.50': 1000.5 }, + 'ipAddress' : { '255.255.255.255': 255255255255, '32.32.32.32': 32032032032, '1.1.1.1': 1001001001 }, + 'url' : { 'http://google.com': 'google.com', 'ftp://fred.com': 'fred.com', 'https://github.com': 'github.com' }, + 'isoDate' : { '2012/12/12': returnTime('2012/12/12'), '2012-12/12': returnTime('2012/12/12'), '2013-1-1': returnTime('2013/1/1'), '2013/1/1 12:34:56 AM': returnTime('2013/1/1 12:34:56 AM') }, + 'percent' : { '100%': 100, '22%': 22, '%2': 2, '2 %': 2, '(4%)': -4, '1,234.56 %': 1234.56 }, + 'usLongDate': { 'Feb 23, 1999': returnTime('Feb 23, 1999'), 'Feb 23, 1999 12:34': returnTime('Feb 23, 1999 12:34'), 'Feb 23, 1999 12:34 AM': returnTime('Feb 23, 1999 12:34 AM'), 'Feb 23, 1999 12:34:56 PM': returnTime('Feb 23, 1999 12:34:56 PM'), '01 Jan 2013': returnTime('01 Jan 2013') }, + 'shortDate' : { '1/2/2001': returnTime('1/2/2001'), '1 2 2001': returnTime('1/2/2001'), '1.2.2001': returnTime('1/2/2001'), '1-2-2001': returnTime('1/2/2001'), '1/2/2001 12:34 PM' : returnTime('1/2/2001 12:34 PM'), '1.2.2001 13:34' : returnTime('1/2/2001 13:34') }, + 'time' : { '12:34 AM': returnTime('2000/01/01 12:34 AM'), '1:00 pm': returnTime('2000/01/01 1:00 pm') }, + 'digit' : { '12': 12, '$23': 23, '&44^': 44, '#(33)': -33, '1,000': 1000, '12.34': 12.34 } + }, + // switch ignoreCase, sortLocalCompare & shortDate "ddmmyyyy" + sample2 = { + 'text' : { 'TesT': 'TesT', '\u00e1 test': 'a test' }, + 'currency' : { '\u20ac 123 456,78': 123456.78, '\u20ac 123.456,78': 123456.78 }, + 'shortDate' : { '2/1/2001': returnTime('1/2/2001'), '2-1-2001': returnTime('1/2/2001'), '2 1,2001': returnTime('1/2/2001') } + }, + // shortdate to "yyyymmdd" + sample3 = { + 'shortDate' : { '2001/1/2': returnTime('1/2/2001'), '2001-1/2': returnTime('1/2/2001'), '2001,1.2': returnTime('1/2/2001') } + }, + report = function(s) { + for (i = 0; i < p.length; i++) { + t = p[i].id; + if (s.hasOwnProperty(t)) { + $.each(s[t], function(k,v){ + // check "is" and "format" functions + if (p[i].is(k)) { + equal( p[i].format(k, table1, th0, 0), v, t + ' parser: "' + k + '" parsed to ' + v ); + } else { + equal( p[i].format(k, table1, th0, 0), v, t + ' parser **NOT DETECTED**: "' + k + '", but returns ' + v ); + } + }); + // test for undefined & null - probably overkill + strictEqual( p[i].format(undef, table1, th0, 0), undef, t + ' parser: will return undefined values properly' ); + strictEqual( p[i].format(null, table1, th0, 0), null, t + ' parser: will return null values properly' ); + } + } + }; + + test( "testing parsers", function() { + expect(parserTests); + report(sample1); + + c1.sortLocaleCompare = true; + c1.ignoreCase = false; + c1.usNumberFormat = false; + th0.dateFormat = c1.dateFormat = "ddmmyyyy"; + report(sample2); + + c1.usNumberFormat = true; + th0.dateFormat = c1.dateFormat = "yyyymmdd"; + report(sample3); + + // undocumented sortValue + equal( ts.getParserById('metadata').format(null, table1, th0, 0), 'zzz', 'metadata parser found sortValue'); + c1.parserMetadataName = 'poe'; + equal( ts.getParserById('metadata').format(null, table1, th0, 0), 'nevermore', 'metadata parser found poe'); + + }); + + /************************************************ + test parser cache + ************************************************/ + test( "parser cache; sorton methods; empty & string", function() { + expect(17); + $table1.trigger('sortReset'); + // lower case because table was parsed before c1.ignoreCase was changed + tester.cacheCompare( table1, 'all', [ 'test2', 'x2', 'test1', 'x3', 'test3', 'x1', '', '', 'testb', 'x5', 'testc', 'x4', 'testa', 'x6' ], 'unsorted' ); + + $table1.trigger('sorton', [[[ 0,0 ]]]); + tester.cacheCompare( table1, 'all', [ 'test1', 'x3', 'test2', 'x2', 'test3', 'x1', '', '', 'testa', 'x6', 'testb', 'x5', 'testc', 'x4' ], 'ascending sort' ); + + $table1.trigger('sorton', [[[ 0,1 ]]]); + tester.cacheCompare( table1, 'all', [ 'test3', 'x1', 'test2', 'x2', 'test1', 'x3', '', '', 'testc', 'x4', 'testb', 'x5', 'testa', 'x6' ], 'descending sort' ); + + // empty cell position + $table3.trigger('sorton', [[[ 0,0 ]]]); + tester.cacheCompare( table3, 0, [ '', 'a1', 'a02', 'a10', 'a33', 'a43', 'a55', 'a87', 'a102', 'a255' ], 'asc sort; empty to top' ); + + $table3.trigger('sorton', [[[ 0,1 ]]]); + tester.cacheCompare( table3, 0, [ '', 'a255', 'a102', 'a87', 'a55', 'a43', 'a33', 'a10', 'a02', 'a1' ], 'desc sort; empty to top' ); + + // string position within number column + $table3.trigger('sorton', [[[ 1,0 ]]]); + tester.cacheCompare( table3, 1, [ -35, -5, -1, 1, 2, 4, 33, 44, 'nr', '' ], 'asc sort; empty to bottom; string to max' ); + + $table3.trigger('sorton', [[[ 1,1 ]]]); + tester.cacheCompare( table3, 1, [ 'nr', 44, 33, 4, 2, 1, -1, -5, -35, '' ], 'desc sort; empty to bottom; string to max' ); + + $table3.trigger('sorton', [[[ 2,0 ]]]); + tester.cacheCompare( table3, 2, [ 'nr', 'nr', 1, 2, 3, 4, 5, 6, 7, '' ], 'asc sort; empty to bottom; string to min' ); + + $table3.trigger('sorton', [[[ 2,1 ]]]); + tester.cacheCompare( table3, 2, [ 7, 6, 5, 4, 3, 2, 1, 'nr', 'nr', '' ], 'desc sort; empty to bottom; string to min' ); + + $table3.trigger('sorton', [[[ 3,0 ]]]); + tester.cacheCompare( table3, 3, [ 'n/a #2', 'n/a #1', -8.4, -2.2, -0.1, '', 5.2, 11.4, 23.6, 97.4 ], 'asc sort; empty to zero; string to top' ); + + $table3.trigger('sorton', [[[ 3,1 ]]]); + tester.cacheCompare( table3, 3, [ 'n/a #2', 'n/a #1', 97.4, 23.6, 11.4, 5.2, '', -0.1, -2.2, -8.4 ], 'desc sort; empty to zero; string to top' ); + + $table3.find('th:eq(3)').data('string', 'bottom'); + $table3.trigger('update'); + tester.cacheCompare( table3, 3, [ 97.4, 23.6, 11.4, 5.2, '', -0.1, -2.2, -8.4, 'n/a #1', 'n/a #2' ], 'desc sort; empty to zero; string to bottom' ); + + $table3.trigger('sorton', [[[ 3,0 ]]]); + tester.cacheCompare( table3, 3, [ -8.4, -2.2, -0.1, '', 5.2, 11.4, 23.6, 97.4, 'n/a #1', 'n/a #2' ], 'asc sort; empty to zero; string to bottom' ); + + $table3.find('th:eq(3)').data('string', 'none'); + c3.headers[3].empty = "bottom"; + c3.sortList = [[ 3, 1 ]]; // added to test sortList + $table3.trigger('update'); + tester.cacheCompare( table3, 3, [ 97.4, 23.6, 11.4, 5.2, 'n/a #1', 'n/a #2', -0.1, -2.2, -8.4, '' ], 'desc sort; empty to zero; string to none/zero' ); + + $table3.trigger('sorton', [[[ 3,0 ]]]); + tester.cacheCompare( table3, 3, [ -8.4, -2.2, -0.1, 'n/a #1', 'n/a #2', 5.2, 11.4, 23.6, 97.4, '' ], 'asc sort; empty to zero; string to none/zero' ); + + t = [ 'x', 'X', 'y', 'Y', 'z', 'Z', 'a', 'A', 'b', 'B', 'c', 'C' ]; + deepEqual( t.sort($.tablesorter.sortText), [ 'A', 'B', 'C', 'X', 'Y', 'Z', 'a', 'b', 'c', 'x', 'y', 'z' ], 'test sortText function directly' ); + + t = [ 'a02', 'a10', 'a43', 'a255', 'a102', 'a33', '', 'a1', 'a55', 'a87' ]; + deepEqual( t.sort($.tablesorter.sortNatural), [ '', 'a1', 'a02', 'a10', 'a33', 'a43', 'a55', 'a87', 'a102', 'a255' ], 'test sortNatural function directly' ); + + }); + + test( "sort Events", function(){ + expect(1); + // table1 sorted twice in the above test; sortIndx = 9 then empty table5 x1 (total = 3 events x 3) + equal( sortIndx, 9, 'sortStart, sortBegin & sortEnd fired in order x3; including empty table' ); + }); + + /************************************************ + test update methods + ************************************************/ + test( "parser cache; update methods & callbacks", function() { + expect(5); + c1.ignoreCase = true; + + // updateAll + $table1 + .find('th:eq(1)').removeAttr('class').html('num').end() + .find('td:nth-child(2)').html(function(i,h){ + return h.substring(1); + }); + $table1.trigger('updateAll', [false, function(){ + updateCallback++; + var nw = $table1.find('th:eq(1)')[0], + hc = c1.headerContent[1] === 'num', + hd = c1.$headers[1] === nw, + hl = c1.headerList[1] === nw, + p1 = c1.parsers[1].id === 'digit'; + equal(hc && hd && hl && p1, true, 'testing header cache: updateAll - thead'); + tester.cacheCompare( table1, 'all', [ 'test3', 1, 'test2', 2, 'test1', 3, '', '', 'testc', 4, 'testb', 5, 'testa', 6 ], 'updateAll - tbody' ); + }]); + + // addRows + t = $('testd7'); + $table1.find('tbody:last').append(t); + $table1.trigger('addRows', [t, true, function(){ + updateCallback++; + tester.cacheCompare( table1, 'all', [ 'test3', 1, 'test2', 2, 'test1', 3, '', '', 'testd', 7, 'testc', 4, 'testb', 5, 'testa', 6 ], 'addRows method' ); + }]); + + // updateCell + t = $table1.find('td:contains("testd")'); + t.html('texte'); + $table1.trigger('updateCell', [t[0], true, function(){ + updateCallback++; + tester.cacheCompare( table1, 'all', [ 'test3', 1, 'test2', 2, 'test1', 3, '', '', 'texte', 7, 'testc', 4, 'testb', 5, 'testa', 6 ], 'updateCell method' ); + }]); + + // update + $table1.find('tr.temp').remove(); + $table1.trigger('update', [true, function(){ + updateCallback++; + tester.cacheCompare( table1, 'all', [ 'test3', 1, 'test2', 2, 'test1', 3, '', '', 'testc', 4, 'testb', 5, 'testa', 6 ], 'update method' ); + }]); + + // update empty table + $table5.trigger('update', [false, function(){ + updateCallback++; + }]); + + }); + + test( "UpdateComplete Event", function(){ + expect(1); + // table1 updated 4x in the above test + // table5 updated 1x + equal( updateIndx, updateCallback, 'updatedComplete and update callback functions working properly' ); + }); + + /************************************************ + test sortForce, sortAppend, sortMultiSortKey and sortResetKey options + ************************************************/ + asyncTest( "sortForce, sortAppend, sortMultiSortKey & sortResetKey", function(){ + expect(3); + var count = 0; + tester.cacheCompare( table4, 3, [ 2, 1, 7, 6, 5, 3, 4, 8, 9, 10 ], 'force x2 + sorted x2 + append x2, ascending' ); + $table4.on('sortEnd', function(){ + count++; + if (count === 1) { + tester.cacheCompare( table4, 3, [ 2, 1, 6, 7, 5, 4, 3, 8, 10, 9 ], 'force x2 + sorted x2 + append x2, descending' ); + c4.sortResetKey = 'shiftKey'; + var e = $.Event('sort'); + e.which = 1; + e.shiftKey = true; // testing sortResetKey + c4.$headers.eq(0).trigger(e); + } else { + tester.cacheCompare( table4, 3, [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], 'sortResetKey' ); + $table4.off('sortEnd'); + start(); + } + }); + var e = $.Event('sort'); + c4.sortMultiSortKey = 'altKey'; + e.which = 1; + e.altKey = true; // testing sortMultiSortKey + c4.$headers.eq(5).trigger(e); + }); + + /************************************************ + check header css + ************************************************/ + test( "testing header css & sortReset method", function(){ + expect(7); + t = $(th0); + equal( $table1.hasClass(ts.css.table), true, 'table class applied'); + equal( t.hasClass(ts.css.header), true, 'Header class present' ); + equal( t.parent().hasClass(ts.css.headerRow), true, 'Header row class present' ); + equal( $table1.find('tbody:eq(1)').hasClass(c1.cssInfoBlock), true, 'Tbody info block class present' ); + $table1.trigger('sorton', [[[ 0,1 ]]] ); + equal( t.hasClass(ts.css.sortDesc), true, 'Descending class present' ); + $table1.trigger('sorton', [[[ 0,0 ]]] ); + equal( t.hasClass(ts.css.sortAsc), true, 'Ascending class present' ); + $table1.trigger('sortReset'); + equal( t.hasClass(ts.css.sortAsc) || t.hasClass(ts.css.sortDesc), false, 'Testing sortReset' ); + }); + + /************************************************ + test apply widgets function using zebra widget + ************************************************/ + var zebra = function(){ + t = true; + $table2.find('tbody tr').each(function(){ + t = t ? $(this).hasClass('odd') || $(this).hasClass('even') : false; + }); + return t; + }; + + test( "apply zebra widget", function(){ + expect(2); + equal( zebra(), false, 'zebra not applied' ); + c2.widgets = [ 'zebra' ]; + $table2.trigger('applyWidgets'); + equal( zebra(), true, 'zebra is applied' ); + }); + + /************************************************ + check destroy method + ************************************************/ + test("testing destroy method", function(){ + $table2.trigger('sorton', [[[ 0,1 ]]] ); + $table2.trigger('destroy'); + expect(7); + t = $table2.find('th:first'); + e = jQuery._data(table2, 'events'); // get a list of all bound events + equal( $.isEmptyObject(e), true, 'no events applied' ); + equal( $table2.data().hasOwnProperty('tablesorter'), false, 'Data removed' ); + equal( $table2.attr('class'), 'tester', 'All table classes removed' ); + equal( $table2.find('tr:first').attr('class'), '', 'Header row class removed' ); + equal( t.attr('class').match('tablesorter'), null, 'Header classes removed' ); + equal( t.children().length, 0, 'Inner wrapper removed' ); + equal( typeof (t.data().column) , 'undefined', 'data-column removed'); + + $table2.tablesorter(); + }); + + /************************************************ + ipv6 parser testing + ************************************************/ + ipv6tests(); + +});