Skip to content
Browse files

filter widget functions

  • Loading branch information...
1 parent 10fe23f commit 1093a3da14fca723b9604f575d19f67eeec8bc66 @Mottie committed Jun 1, 2012
View
BIN README.markdown
Binary file not shown.
View
BIN css/blue/blue.zip
Binary file not shown.
View
6 css/blue/style.css
@@ -95,7 +95,8 @@ table.tablesorter tr.even td.tertiary {
}
/* filter widget */
-table.tablesorter input.tablesorter-filter {
+table.tablesorter input.tablesorter-filter,
+table.tablesorter select.tablesorter-filter {
width: 95%;
height: inherit;
-webkit-box-sizing: border-box;
@@ -108,7 +109,8 @@ table.tablesorter tr.tablesorter-filter td {
background: #fff;
}
/* optional disabled input styling */
-table.tablesorter input.tablesorter-filter.disabled {
+table.tablesorter input.tablesorter-filter.disabled,
+table.tablesorter select.tablesorter-filter.disabled {
opacity: 0.5;
filter: alpha(opacity=50);
}
View
BIN css/green/green.zip
Binary file not shown.
View
6 css/green/style.css
@@ -87,7 +87,8 @@ table.tablesorter tr.even td.tertiary {
}
/* filter widget */
-table.tablesorter input.tablesorter-filter {
+table.tablesorter input.tablesorter-filter,
+table.tablesorter select.tablesorter-filter {
width: 95%;
height: inherit;
-webkit-box-sizing: border-box;
@@ -100,7 +101,8 @@ table.tablesorter tr.tablesorter-filter td {
background: #fff;
}
/* optional disabled input styling */
-table.tablesorter input.tablesorter-filter.disabled {
+table.tablesorter input.tablesorter-filter.disabled,
+table.tablesorter select.tablesorter-filter.disabled {
opacity: 0.5;
filter: alpha(opacity=50);
}
View
6 css/ui/style.css
@@ -47,7 +47,8 @@ table.tablesorter .tablesorter-hidden {
}
/* filter widget */
-table.tablesorter thead tr.tablesorter-filter input.tablesorter-filter {
+table.tablesorter thead tr.tablesorter-filter input.tablesorter-filter,
+table.tablesorter thead tr.tablesorter-filter select.tablesorter-filter {
width: 95%;
height: inherit;
-webkit-box-sizing: border-box;
@@ -59,7 +60,8 @@ table.tablesorter thead tr.tablesorter-filter td {
text-align: center;
}
/* optional disabled input styling */
-table.tablesorter thead tr.tablesorter-filter input.tablesorter-filter.disabled {
+table.tablesorter thead tr.tablesorter-filter input.tablesorter-filter.disabled,
+table.tablesorter thead tr.tablesorter-filter select.tablesorter-filter.disabled {
opacity: 0.5;
filter: alpha(opacity=50);
}
View
335 docs/example-widget-filter-custom.html
@@ -0,0 +1,335 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>jQuery plugin: Tablesorter 2.0 - Custom Filter Widget</title>
+
+ <!-- jQuery -->
+ <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
+
+ <!-- Demo stuff -->
+ <link rel="stylesheet" href="css/jq.css">
+ <script src="js/chili/jquery.chili-2.2.js"></script>
+ <script src="js/chili/recipes.js"></script>
+ <script src="js/docs.js"></script>
+
+ <!-- Tablesorter: required -->
+ <link rel="stylesheet" href="../css/blue/style.css">
+ <script src="../js/jquery.tablesorter.js"></script>
+ <script src="../js/jquery.tablesorter.widgets.js"></script>
+
+ <!-- Tablesorter: optional -->
+ <!-- <script src="../addons/pager/jquery.tablesorter.pager.js"></script> -->
+
+<script id="js">$(function() {
+
+ // call the tablesorter plugin
+ $("table").tablesorter({
+
+ // initialize zebra striping and filter widgets
+ widgets: ["zebra", "filter"],
+
+ // headers: { 5: { sorter: false, filter: false } },
+
+ widgetOptions : {
+
+ // css class applied to the table row containing the filters & the inputs within that row
+ filter_cssFilter : 'tablesorter-filter',
+
+ // If there are child rows in the table (rows with class name from "cssChildRow" option)
+ // and this option is true and a match is found anywhere in the child row, then it will make that row
+ // visible; default is false
+ filter_childRows : false,
+
+ // Set this option to true to use the filter to find text from the start of the column
+ // So typing in "a" will find "albert" but not "frank", both have a's; default is false
+ filter_startsWith : false,
+
+ // Set this option to false to make the searches case sensitive
+ filter_ignoreCase : true,
+
+ // Delay in milliseconds before the filter widget starts searching; This option prevents searching for
+ // every character while typing and should make searching large tables faster.
+ filter_searchDelay : 300,
+
+ // Add select box to 4th column (zero-based index)
+ // each option has an associated function that returns a boolean
+ // function variables:
+ // e = exact text from cell
+ // n = normalized value returned by the column parser
+ // f = search filter input value
+ // i = column index
+ filter_functions : {
+
+ // Add select menu to this column
+ // set the column value to true, and/or add "filter-select" class name to header
+ // 0 : true,
+
+ // Exact match only
+ 1 : function(e, n, f, i) {
+ return e === f;
+ },
+
+ // Add these options to the select dropdown (regex example)
+ 2 : {
+ "A - D" : function(e, n, f, i) { return /^[A-D]/.test(e); },
+ "E - H" : function(e, n, f, i) { return /^[E-H]/.test(e); },
+ "I - L" : function(e, n, f, i) { return /^[I-L]/.test(e); },
+ "M - P" : function(e, n, f, i) { return /^[M-P]/.test(e); },
+ "Q - T" : function(e, n, f, i) { return /^[Q-T]/.test(e); },
+ "U - X" : function(e, n, f, i) { return /^[U-X]/.test(e); },
+ "Y - Z" : function(e, n, f, i) { return /^[Y-Z]/.test(e); }
+ },
+
+ // Add these options to the select dropdown (numerical comparison example)
+ // Note that only the normalized (n) value will contain numerical data
+ // If you use the exact text, you'll need to parse it (parseFloat or parseInt)
+ 4 : {
+ "< $10" : function(e, n, f, i) { return n < 10; },
+ "$10 - $100" : function(e, n, f, i) { return n >= 10 && n <=100; },
+ "> $100" : function(e, n, f, i) { return n > 100; }
+ }
+ }
+
+ }
+// ,debug: true
+ });
+
+});</script>
+
+<script>
+$(function(){
+ // *** widgetfilter_startsWith toggle button ***
+ $('button.toggle').click(function(){
+ var c = $('table')[0].config,
+ // toggle the boolean
+ fsw = !c.widgetOptions.filter_startsWith,
+ fic = !c.widgetOptions.filter_ignoreCase;
+ if ($(this).hasClass('fsw')) {
+ c.widgetOptions.filter_startsWith = fsw;
+ $('#start').html(fsw.toString());
+ } else {
+ c.widgetOptions.filter_ignoreCase = fic;
+ $('#case').html(fic.toString());
+ }
+ // update search after option change; add false to trigger to skip search delay
+ $('input.tablesorter-filter:eq(0)').trigger('search', false);
+ });
+});
+</script>
+
+</head>
+<body>
+<div id="banner">
+ <h1>table<em>sorter</em></h1>
+ <h2>Custom Filter Widget</h2>
+ <h3>Flexible client-side table sorting</h3>
+ <a href="index.html">Back to documentation</a>
+</div>
+<div id="main">
+
+ <p class="tip">
+ <em>NOTE!</em>
+ Custom filter widget option <code class="hilight">filter_functions</code> was added in version 2.3.6:
+ <ul>
+ <li><strong>Default Select</strong> - See the "First Name" column below.
+ <ul>
+ <li>To enable this type of select, set the <code class="hilight">filter_functions</code> option for the column to <code class="hilight">true</code>, and/or add a "filter-select" class to the column header cell.</li>
+ <li>The default option text, "Select a name", is obtained from the header <code class="hilight">data-placeholder</code> attribute of the column header cell. And when active, it will show all table rows.</li>
+ <li>The select is populated by the column text contents with repeated content combined (i.e. There are three "Aaron"'s in the first column, but only one in the dropdown.</li>
+ <li>Select options are automatically sorted.</li>
+ </ul>
+ </li>
+ <li><strong>Custom Select</strong> - See the "Total" column.
+ <ul>
+ <li>To enable this type of select, add your custom options within the <code class="hilight">filter_functions</code> option.</li>
+ <li>Each option is set as a "key:value" pair where the "key" is the actual text of the option and the "value" is the function associated with the option. See the example below.</li>
+ <li>See the filter function information below.</li>
+ </ul>
+ </li>
+ <li><strong>Custom Filter Function</strong> - See the "Last Name" column.
+ <ul>
+ <li>To enable this type of filter, add your custom function to the <code class="hilight">filter_functions</code> option following the example below.</li>
+ <li>The example below shows you how to show only exact matches. The problem with this is that you can't see the matches while typing unless you set the <code class="hilight">filter_searchDelay</code> option to be a bit longer.</li>
+ <li>Also, the example only checks for an exact match (<code class="hilight">===</code>) meaning the <code class="hilight">filter_ignoreCase</code> option is ignored, but other comparisons can be made using regex and the insensitive "i" flag.</li>
+ <li>See the filter function information below.</li>
+ </ul>
+ </li>
+
+ <li><strong>Filter function information</strong>:
+ <ul>
+ <li>The custom function must return a boolean value. If <code class="hilight">true</code> is returned, the row will be shown if all other filters match; and if <code class="hilight">false</code> is returned, the row will be hidden.</li>
+ <li>The <strong>exact text (e)</strong> of the table cell is a variable passed to the function. Note that numbers will need to be parsed to make comparisons.</li>
+ <li><strong>Normalized table cell data (n)</strong> is the next varibale passed to the function.
+ <ul>
+ <li>This data has been parsed by the assigned column parser, so make sure the same type of data is being compared as parsed data may not be what you expect.</li>
+ <li>Normalized numerical values within the table will be of numeric type and not of string type, as the sorter needs to use mathematical comparisons while sorting.</li>
+ <li>The data will be in lower-case if the <code class="hilight">filter_ignoreCase</code> option is <code class="hilight">true</code>.</li>
+ <li>Dates like in the last column of the table below will store the time in seconds since 1970 (using javascript's .getTime() function).</li>
+ <li>The percentage column will only store the number and not percentage sign.</li>
+ </ul>
+ </li>
+ <li>The <strong>filter input value (f)</strong> is the exact text entered by the user. If numerical, it will need to be parsed using parseFloat() or parseInt() to allow for making comparisons.</li>
+ <li>The <strong>column index (i)</strong> might be useful for obtaining more information from header, or something.</li>
+ </ul>
+ </li>
+ </ul>
+ </p>
+
+ <h1>Demo</h1>
+ <button class="toggle fsw">Toggle</button> filter_startsWith : <span id="start">false</span> (if true, search from beginning of cell content only)<br>
+ <button class="toggle fic">Toggle</button> filter_ignoreCase : <span id="case">true</span> (if false, the search will be case sensitive)
+
+ <div id="demo"><table class="tablesorter">
+ <thead>
+ <tr>
+ <th class="filter-select" data-placeholder="Select a name">First Name</th> <!-- add "filter-select" class or filter_functions : { 0: true } -->
+ <th data-placeholder="Exact matches only">Last Name</th>
+ <th data-placeholder="Choose a city">City</th>
+ <th>Age</th>
+ <th data-placeholder="Select a filter">Total</th>
+ <th>Discount</th>
+ <th>Date</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>Aaron</td>
+ <td>Johnson Sr</td>
+ <td>Atlanta</td>
+ <td>35</td>
+ <td>$5.95</td>
+ <td>22%</td>
+ <td>Jun 26, 2004 7:22 AM</td>
+ </tr>
+ <tr>
+ <td>Aaron</td>
+ <td>Johnson</td>
+ <td>Yuma</td>
+ <td>12</td>
+ <td>$2.99</td>
+ <td>5%</td>
+ <td>Aug 21, 2009 12:21 PM</td>
+ </tr>
+ <tr>
+ <td>Clark</td>
+ <td>Henry Jr</td>
+ <td>Tampa</td>
+ <td>51</td>
+ <td>$42.29</td>
+ <td>18%</td>
+ <td>Oct 13, 2000 1:15 PM</td>
+ </tr>
+ <tr>
+ <td>Peter</td>
+ <td>Henry</td>
+ <td>New York</td>
+ <td>28</td>
+ <td>$9.99</td>
+ <td>20%</td>
+ <td>Jul 6, 2006 8:14 AM</td>
+ </tr>
+ <tr>
+ <td>John</td>
+ <td>Hood</td>
+ <td>Boston</td>
+ <td>33</td>
+ <td>$19.99</td>
+ <td>25%</td>
+ <td>Dec 10, 2002 5:14 AM</td>
+ </tr>
+ <tr>
+ <td>Clark</td>
+ <td>Kent Sr</td>
+ <td>Los Angeles</td>
+ <td>18</td>
+ <td>$15.89</td>
+ <td>44%</td>
+ <td>Jan 12, 2003 11:14 AM</td>
+ </tr>
+ <tr>
+ <td>John</td>
+ <td>Kent Esq</td>
+ <td>Seattle</td>
+ <td>45</td>
+ <td>$153.19</td>
+ <td>44%</td>
+ <td>Jan 18, 2021 9:12 AM</td>
+ </tr>
+ <tr>
+ <td>Peter</td>
+ <td>Johns</td>
+ <td>Milwaukee</td>
+ <td>13</td>
+ <td>$5.29</td>
+ <td>4%</td>
+ <td>Jan 8, 2012 5:11 PM</td>
+ </tr>
+ <tr>
+ <td>Aaron</td>
+ <td>Evan</td>
+ <td>Chicago</td>
+ <td>24</td>
+ <td>$14.19</td>
+ <td>14%</td>
+ <td>Jan 14, 2004 11:23 AM</td>
+ </tr>
+ <tr>
+ <td>Bruce</td>
+ <td>Evans</td>
+ <td>Upland</td>
+ <td>22</td>
+ <td>$13.19</td>
+ <td>11%</td>
+ <td>Jan 18, 2007 9:12 AM</td>
+ </tr>
+ <tr>
+ <td>Clark</td>
+ <td>McMasters</td>
+ <td>Pheonix</td>
+ <td>18</td>
+ <td>$55.20</td>
+ <td>15%</td>
+ <td>Feb 12, 2010 7:23 PM</td>
+ </tr>
+ <tr>
+ <td>Dennis</td>
+ <td>Masters</td>
+ <td>Indianapolis</td>
+ <td>65</td>
+ <td>$123.00</td>
+ <td>32%</td>
+ <td>Jan 20, 2001 1:12 PM</td>
+ </tr>
+ <tr>
+ <td>John</td>
+ <td>Hood</td>
+ <td>Fort Worth</td>
+ <td>25</td>
+ <td>$22.09</td>
+ <td>17%</td>
+ <td>Jun 11, 2011 10:55 AM</td>
+ </tr>
+ </tbody>
+</table></div>
+
+ <h1>Javascript</h1>
+ <div id="javascript">
+ <pre class="js"></pre>
+ </div>
+
+ <h1>HTML</h1>
+ <div id="html">
+ <pre class="html"></pre>
+ </div>
+
+<div class="next-up">
+ <hr />
+ Next up: <a href="example-widget-ui-theme.html">jQuery UI theme widget &rsaquo;&rsaquo;</a>
+</div>
+
+</div>
+
+</body>
+</html>
+
View
45 docs/example-widget-filter.html
@@ -29,7 +29,7 @@
// initialize zebra striping and filter widgets
widgets: ["zebra", "filter"],
- headers: { 5: { sorter: false, filter: false } },
+ // headers: { 5: { sorter: false, filter: false } },
widgetOptions : {
@@ -50,10 +50,13 @@
// Delay in milliseconds before the filter widget starts searching; This option prevents searching for
// every character while typing and should make searching large tables faster.
- filter_searchDelay : 300
+ filter_searchDelay : 300,
- }
+ // See the filter widget advanced demo on how to use these special functions
+ filter_functions : {}
+ }
+// ,debug: true
});
});</script>
@@ -92,6 +95,20 @@
<p class="tip">
<em>NOTE!</em>
<ul>
+ <li>In version 2.3.6, these changes were made:
+ <ul>
+ <li>Include filter input boxes placeholder text by adding <code class="hilight">data-placeholder</code> to the column header cell; e.g. <code class="hilight">data-placeholder="First Name"</code>. See the examples in the HTML code block below.</li>
+ <li>Exact match added. Add a quote (single or double) to the end of the string to find an exact match. In the first column enter <code class="hilight">Clark"</code> to only find Clark and not Brandon Clark.</li>
+ <li>Wild cards added:
+ <ul>
+ <li><code class="hilight">?</code> (question mark) finds any single non-space character.<br>In the discount column, adding <code class="hilight">1?%</code> in the filter will find all percentages between "10%" and "19%". In the last column, <code class="hilight">J?n</code> will find "Jun" and "Jan".</li>
+ <li><code class="hilight">*</code> (asterisk) finds multiple non-space characters.<br>In the first column below Enter <code class="hilight">Br*</code> will find multiple names starting with "Br". Now add a space at the end, and "Bruce" will not be included in the results.</li>
+ </ul>
+ </li>
+ <li>Regex method added. Use standard regex within the filter to filter the columns. For example enter <code class="hilight">/20[1-9]\d/</code> or <code class="hilight">/20[^0]\d/</code> in the last column to find all dates greater than 2009.</li>
+ <li>Added <code class="hilight">filter_functions</code> option which allows you to add a custom filter function for a column or to a dropdown list. Please see the <a href="example-widget-filter-custom.html">jQuery filter widget, advanced</a> demo for more details.</a></li>
+ </ul>
+ </li>
<li>In version 2.0.19.1, a filter header option and header class name check was added to allow disabling the filter in a specific column.</li>
<li>In versions 2.3+, the filter widget can be disabled using any of the following methods, in order of priority:
<ul>
@@ -120,18 +137,18 @@
<div id="demo"><table class="tablesorter">
<thead>
<tr>
- <th>First Name</th>
+ <th data-placeholder="Try Br*{space}">First Name</th>
<th>Last Name</th>
<th>Age</th>
<th>Total</th>
- <th class="filter-false">Discount</th> <!-- disable filter in this column -->
- <th>Date</th>
+ <th data-placeholder="Try 1?%">Discount</th> <!-- add class="filter-false" to disable the filter in this column -->
+ <th data-placeholder="Try /20[^0]\d/">Date</th>
</tr>
</thead>
<tbody>
<tr>
- <td>Philip</td>
- <td>Johnson</td>
+ <td>Philip Aaron</td>
+ <td>Johnson Sr Esq</td>
<td>25</td>
<td>$5.95</td>
<td>22%</td>
@@ -146,7 +163,7 @@
<td>Aug 21, 2009 12:21 PM</td>
</tr>
<tr>
- <td>Brandon</td>
+ <td>Brandon Clark</td>
<td>Henry Jr</td>
<td>51</td>
<td>$42.29</td>
@@ -183,14 +200,14 @@
<td>45</td>
<td>$153.19</td>
<td>44%</td>
- <td>Jan 18, 2001 9:12 AM</td>
+ <td>Jan 18, 2021 9:12 AM</td>
</tr>
<tr>
<td>Alex</td>
<td>Dumass</td>
<td>13</td>
<td>$5.29</td>
- <td>2%</td>
+ <td>4%</td>
<td>Jan 8, 2012 5:11 PM</td>
</tr>
<tr>
@@ -202,7 +219,7 @@
<td>Jan 14, 2004 11:23 AM</td>
</tr>
<tr>
- <td>Bruce</td>
+ <td>Bruce Lee</td>
<td>Evans</td>
<td>22</td>
<td>$13.19</td>
@@ -223,7 +240,7 @@
<td>65</td>
<td>$123.00</td>
<td>32%</td>
- <td>Jan 22, 2001 1:12 PM</td>
+ <td>Jan 20, 2001 1:12 PM</td>
</tr>
<tr>
<td>Martha</td>
@@ -279,7 +296,7 @@
<div class="next-up">
<hr />
- Next up: <a href="example-widget-ui-theme.html">jQuery UI theme widget &rsaquo;&rsaquo;</a>
+ Next up: <a href="example-widget-filter-custom.html">jQuery filter widget, advanced &rsaquo;&rsaquo;</a>
</div>
</div>
View
124 docs/index.html
@@ -288,6 +288,7 @@
<li><a href="example-apply-widget.html">Applying widgets</a></li>
<li><a href="example-widget-columns.html">Columns widget</a> (v2.0.17)</li>
<li><a href="example-widget-filter.html">Filter widget</a> (v2.0.18)</li>
+ <li><a href="example-widget-filter-custom.html">Filter widget, custom</a> <span class="tip"><em>New!</em></span> v2.3.6</li>
<li><a href="example-widget-ui-theme.html">jQuery UI theme widget</a> (v2.0.9)</li>
<li><a href="example-widget-resizable.html">Resizable Columns widget</a> (v2.0.23.1)</li>
<li><a href="example-widget-savesort.html">Save sort widget</a> (v2.0.27)</li>
@@ -678,6 +679,22 @@
<td></td>
</tr>
+ <tr id="initwidgets">
+ <td><a href="#" class="toggle2">initWidgets</a></td>
+ <td>Boolean</td>
+ <td>true</td>
+ <td>Apply widgets after table initializes <span class="tip"><em>New!</em></span> v2.3.5.
+ <div class="collapsible">
+ When true, all widgets set by the <code class="hilight">widgets</code> option will apply after tablesorter has initialized, this is the normal behavior.<br>
+ <br>
+ If false, the each widget set by the <code class="hilight">widgets</code> option will be initialized, meaning the "init" function is run, but the format function will not be run. This is useful when running the pager plugin after the table is set up. The pager plugin will initialize, then apply all set widgets.<br>
+ <br>
+ Why you ask? Well, lets say you have a table with 1000 rows that will have the pager plugin applied to it. Before this option, the table would finish its setup, all widgets would be applied to the 1000 rows, pager plugin initializes and reapplies the widgets on the say 20 rows showing; making the widget application to 100 rows unnecessary and a waste of time. So, when this option is false, widgets will only be applied to the table after the pager is set up.
+ </div>
+ </td>
+ <td></td>
+ </tr>
+
<tr id="onrenderheader">
<td><a href="#" class="toggle2">onRenderHeader</a></td>
<td>Function</td>
@@ -1319,6 +1336,113 @@
<td><a href="example-widget-filter.html">Example</a></td>
</tr>
+ <tr id="widget-filter-functions">
+ <td><a href="#" class="toggle2">filter_functions</a></td>
+ <td>Object</td>
+ <td>null</td>
+ <td>
+ Customize the filter widget by adding a select dropdown with content, custom options or custom filter functions. <span class="tip"><em>New! v2.3.6</em></span>
+ <div class="collapsible">
+ <br>
+ Use the <a href="#widget-filter-functions"><code class="hilight">"filter_functions"</code></a> option in three different ways:
+ <br>
+ <ul>
+ <li>
+ Make a select dropdown list of all column contents. Repeated content will be combined.
+ <pre class="js">$(function(){
+ $("table").tablesorter({
+ widgets: ["filter"],
+ widgetOptions: {
+ filter_functions: {
+ // Add select menu to this column
+ // set the column value to true, and/or add "filter-select" class name to header
+ 0 : true
+ }
+ }
+ });
+});</pre>
+ Alternately, instead of setting the column filter funtion to true, give the column header a class name of "filter-select". See the <a href="example-widget-filter-custom.html">demo</a>.<br><br>
+ </li>
+ <li>
+ Make a select dropdown list with custom option settings. Each option must have a corresponding function which returns a boolean value; return true if there is a match, or false with no match.
+
+ <h4>Regex example</h4>
+ <pre class="js">$(function(){
+ $("table").tablesorter({
+ widgets: ["filter"],
+ widgetOptions: {
+ // function variables:
+ // e = exact text from cell
+ // n = normalized value returned by the column parser
+ // f = search filter input value
+ // i = column index
+ filter_functions: {
+ // Add these options to the select dropdown (regex example)
+ 2 : {
+ "A - D" : function(e, n, f, i) { return /^[A-D]/.test(e); },
+ "E - H" : function(e, n, f, i) { return /^[E-H]/.test(e); },
+ "I - L" : function(e, n, f, i) { return /^[I-L]/.test(e); },
+ "M - P" : function(e, n, f, i) { return /^[M-P]/.test(e); },
+ "Q - T" : function(e, n, f, i) { return /^[Q-T]/.test(e); },
+ "U - X" : function(e, n, f, i) { return /^[U-X]/.test(e); },
+ "Y - Z" : function(e, n, f, i) { return /^[Y-Z]/.test(e); }
+ }
+ }
+ }
+ });
+});</pre>
+ <h4>Comparison example</h4>
+ <pre class="js">$(function(){
+ $("table").tablesorter({
+ widgets: ["filter"],
+ widgetOptions: {
+ // function variables:
+ // e = exact text from cell
+ // n = normalized value returned by the column parser
+ // f = search filter input value
+ // i = column index
+ filter_functions: {
+ // Add these options to the select dropdown (numerical comparison example)
+ // Note that only the normalized (n) value will contain numerical data
+ // If you use the exact text, you'll need to parse it (parseFloat or parseInt)
+ 4 : {
+ "< $10" : function(e, n, f, i) { return n < 10; },
+ "$10 - $100" : function(e, n, f, i) { return n >= 10 && n <=100; },
+ "> $100" : function(e, n, f, i) { return n > 100; }
+ }
+ }
+ }
+ });
+});</pre>
+ Note: if the <code class="hilight">filter_ignoreCase</code> option is <code class="hilight">true</code>, it DOES alter the normalized value (n) by making it all lower case.<br><br>
+ </li>
+ <li>
+ Make a custom filter for the column.
+ <pre class="js">$(function(){
+ $("table").tablesorter({
+ widgets: ["filter"],
+ widgetOptions: {
+ // function variables:
+ // e = exact text from cell
+ // n = normalized value returned by the column parser
+ // f = search filter input value
+ // i = column index
+ filter_functions: {
+ // Exact match only
+ 1 : function(e, n, f, i) {
+ return e === f;
+ }
+ }
+ }
+ });
+});</pre>
+ Note: if the <code class="hilight">filter_ignoreCase</code> option is <code class="hilight">true</code>, it DOES alter the normalized value (n) by making it all lower case.<br><br>
+ </li>
+ </ul>
+ </div>
+ </td>
+ <td><a href="example-widget-filter-custom.html">Example</a></td>
+ </tr>
<tr id="widget-filter-searchdelay">
<td><a href="#" class="toggle2">filter_searchDelay</a></td>
View
4 js/jquery.tablesorter.js
@@ -1,5 +1,5 @@
/*!
-* TableSorter 2.3.5 - Client-side table sorting with ease!
+* TableSorter 2.3.6 - Client-side table sorting with ease!
* @requires jQuery v1.2.6+
*
* Copyright (c) 2007 Christian Bach
@@ -18,7 +18,7 @@
$.extend({
tablesorter: new function() {
- this.version = "2.3.5";
+ this.version = "2.3.6";
var parsers = [], widgets = [];
this.defaults = {
View
4 js/jquery.tablesorter.min.js
@@ -1,6 +1,6 @@
/*!
-* TableSorter 2.3.5 - Client-side table sorting with ease!
+* TableSorter 2.3.6 - Client-side table sorting with ease!
* Minified using UglifyJS (http://jscompress.com/)
* Copyright (c) 2007 Christian Bach
*/
-!function($){$.extend({tablesorter:new function(){function log(a){if(typeof console!=="undefined"&&typeof console.log!=="undefined"){console.log(a)}else{alert(a)}}function benchmark(a,b){log(a+" ("+((new Date).getTime()-b.getTime())+"ms)")}function getElementText(a,b,c){if(!b){return""}var d=a.config,e=d.textExtraction,f="";if(e==="simple"){if(d.supportsTextContent){f=b.textContent}else{if(b.childNodes[0]&&b.childNodes[0].hasChildNodes()){f=b.childNodes[0].innerHTML}else{f=b.innerHTML}}}else{if(typeof e==="function"){f=e(b,a,c)}else if(typeof e==="object"&&e.hasOwnProperty(c)){f=e[c](b,a,c)}else{f=d.supportsTextContent?b.textContent:$(b).text()}}return $.trim(f)}function getParserById(a){var b,c=parsers.length;for(b=0;b<c;b++){if(parsers[b].id.toLowerCase()===a.toString().toLowerCase()){return parsers[b]}}return false}function detectParserForColumn(a,b,c,d){var e,f=parsers.length,g=false,h="",i=true;while(h===""&&i){c++;if(b[c]){g=b[c].cells[d];h=getElementText(a,g,d);if(a.config.debug){log("Checking if value was empty on row "+c+", column: "+d+": "+h)}}else{i=false}}for(e=1;e<f;e++){if(parsers[e].is(h,a,g)){return parsers[e]}}return parsers[0]}function buildParserCache(a,b){var c=a.config,d=$(a.tBodies).filter(":not(."+c.cssInfoBlock+")"),e=$.tablesorter,f,g,h,i,j,k,l,m,n,o="";if(d.length===0){return}f=d[0].rows;if(f[0]){g=[];h=f[0].cells.length;for(i=0;i<h;i++){j=b.filter(':not([colspan])[data-column="'+i+'"]:last,[colspan="1"][data-column="'+i+'"]:last');l=c.headers[i];n=getParserById(e.getData(j,l,"sorter"));c.empties[i]=e.getData(j,l,"empty")||c.emptyTo||(c.emptyToBottom?"bottom":"top");c.strings[i]=e.getData(j,l,"string")||c.stringTo||"max";if(!n){n=detectParserForColumn(a,f,-1,i)}if(c.debug){o+="column:"+i+"; parser:"+n.id+"; string:"+c.strings[i]+"; empty: "+c.empties[i]+"\n"}g.push(n)}}if(c.debug){log(o)}return g}function buildRegex(){var a,b="[",c=$.tablesorter,d=c.characterEquivalents;c.characterRegexArray={};for(a in d){if(typeof a==="string"){b+=d[a];c.characterRegexArray[a]=new RegExp("["+d[a]+"]","g")}}c.characterRegex=new RegExp(b+"]")}function buildCache(a){var b=a.tBodies,c=a.config,d,e,f=c.parsers,g,h,i,j,k,l,m;c.cache={};if(c.debug){m=new Date}for(j=0;j<b.length;j++){c.cache[j]={row:[],normalized:[]};if(!$(b[j]).hasClass(c.cssInfoBlock)){$(b[j]).addClass("tablesorter-hidden");d=b[j]&&b[j].rows.length||0;e=b[j].rows[0]&&b[j].rows[0].cells.length||0;for(h=0;h<d;++h){k=$(b[j].rows[h]);l=[];if(k.hasClass(c.cssChildRow)){c.cache[j].row[c.cache[j].row.length-1]=c.cache[j].row[c.cache[j].row.length-1].add(k);continue}c.cache[j].row.push(k);for(i=0;i<e;++i){g=getElementText(a,k[0].cells[i],i);l.push(f[i].format(g,a,k[0].cells[i],i))}l.push(c.cache[j].normalized.length);c.cache[j].normalized.push(l)}$(b[j]).removeClass("tablesorter-hidden")}}if(c.debug){benchmark("Building cache for "+d+" rows",m)}}function getWidgetById(a){var b,c,d=widgets.length;for(b=0;b<d;b++){c=widgets[b];if(c&&c.hasOwnProperty("id")&&c.id.toLowerCase()===a.toLowerCase()){return c}}}function applyWidget(a,b){var c=a.config,d=c.widgets,e,f,g,h=d.length;if(c.debug){e=new Date}for(f=0;f<h;f++){g=getWidgetById(d[f]);if(g){if(b===true&&g.hasOwnProperty("init")){g.init(a,widgets,g)}else if(!b&&g.hasOwnProperty("format")){g.format(a)}}}if(c.debug){benchmark("Completed "+(b===true?"initializing":"applying")+" widgets",e)}}function appendToTable(a,b){var c=a.config,d=a.tBodies,e=[],f,g,h,i,j=c.cache,k,l,m,n,o,p,q;if(c.debug){q=new Date}for(n=0;n<d.length;n++){if(!$(d[n]).hasClass(c.cssInfoBlock)){$(d[n]).addClass("tablesorter-hidden");k=document.createDocumentFragment();f=j[n].row;g=j[n].normalized;h=g.length;i=h?g[0].length-1:0;for(l=0;l<h;l++){p=g[l][i];e.push(f[p]);if(!c.appender||!c.removeRows){o=f[p].length;for(m=0;m<o;m++){k.appendChild(f[p][m])}}}a.tBodies[n].appendChild(k);$(d[n]).removeClass("tablesorter-hidden")}}if(c.appender){c.appender(a,e)}if(c.debug){benchmark("Rebuilt table",q)}if(!b){applyWidget(a)}$(a).trigger("sortEnd",a)}function computeThIndexes(a){var b=[],c={},d=$(a).find("thead:eq(0) tr"),e,f,g,h,i,j,k,l,m,n,o,p;for(e=0;e<d.length;e++){j=d[e].cells;for(f=0;f<j.length;f++){i=j[f];k=i.parentNode.rowIndex;l=k+"-"+i.cellIndex;m=i.rowSpan||1;n=i.colSpan||1;if(typeof b[k]==="undefined"){b[k]=[]}for(g=0;g<b[k].length+1;g++){if(typeof b[k][g]==="undefined"){o=g;break}}c[l]=o;$(i).attr({"data-column":o});for(g=k;g<k+m;g++){if(typeof b[g]==="undefined"){b[g]=[]}p=b[g];for(h=o;h<o+n;h++){p[h]="x"}}}}return c}function formatSortingOrder(a){return/^d/i.test(a)||a===1}function buildHeaders(a){var b=computeThIndexes(a),c,d,e,f,g,h,i=a.config,j=$.tablesorter;i.headerList=[];if(i.debug){g=new Date}h=$(a).find(i.selectorHeaders).each(function(a){d=$(this);c=i.headers[a];this.innerHTML='<div class="tablesorter-header-inner">'+this.innerHTML+"</div>";if(i.onRenderHeader){i.onRenderHeader.apply(e,[a])}this.column=b[this.parentNode.rowIndex+"-"+this.cellIndex];this.order=formatSortingOrder(j.getData(d,c,"sortInitialOrder")||i.sortInitialOrder)?[1,0,2]:[0,1,2];this.count=-1;if(j.getData(d,c,"sorter")==="false"){this.sortDisabled=true}this.lockedOrder=false;f=j.getData(d,c,"lockedOrder")||false;if(typeof f!=="undefined"&&f!==false){this.order=this.lockedOrder=formatSortingOrder(f)?[1,1,1]:[0,0,0]}if(!this.sortDisabled){e=d.addClass(i.cssHeader)}i.headerList[a]=this;d.parent().addClass(i.cssHeader)});if(a.config.debug){benchmark("Built headers:",g);log(h)}return h}function isValueInArray(a,b){var c,d=b.length;for(c=0;c<d;c++){if(b[c][0]===a){return true}}return false}function setHeadersCss(a,b,c){var d,e=[],f,g,h,i=[a.config.cssDesc,a.config.cssAsc];b.removeClass(i.join(" ")).each(function(){if(!this.sortDisabled){e[this.column]=$(this)}});h=c.length;for(f=0;f<h;f++){if(c[f][1]===2){continue}if(e[c[f][0]]){e[c[f][0]].addClass(i[c[f][1]])}d=b.filter('[data-column="'+c[f][0]+'"]');if(h>1&&d.length){for(g=0;g<d.length;g++){if(!d[g].sortDisabled){$(d[g]).addClass(i[c[f][1]])}}}}}function fixColumnWidth(a){if(a.config.widthFixed){var b=$("<colgroup>");$("tr:first td",a.tBodies[0]).each(function(){b.append($("<col>").css("width",$(this).width()))});$(a).prepend(b)}}function updateHeaderSortCount(a,b){var c,d,e,f=a.config,g=b.length;for(c=0;c<g;c++){d=b[c];e=f.headerList[d[0]];e.count=d[1]%(f.sortReset?3:2)}}function getCachedSortType(a,b){return a&&a[b]?a[b].type||"":""}function multisort(table,sortList){var dynamicExp,col,mx=0,dir=0,tc=table.config,l=sortList.length,bl=table.tBodies.length,sortTime,i,j,k,c,cache,lc,s,e,order,orgOrderCol;if(tc.debug){sortTime=new Date}for(k=0;k<bl;k++){dynamicExp="var sortWrapper = function(a,b) {";cache=tc.cache[k];lc=cache.normalized.length;for(i=0;i<l;i++){c=sortList[i][0];order=sortList[i][1];s=/n/i.test(getCachedSortType(tc.parsers,c))?"Numeric":"Text";s+=order===0?"":"Desc";e="e"+i;if(/Numeric/.test(s)&&tc.strings[c]){for(j=0;j<lc;j++){col=Math.abs(parseFloat(cache.normalized[j][c]));mx=Math.max(mx,isNaN(col)?0:col)}if(typeof tc.string[tc.strings[c]]==="boolean"){dir=(order===0?1:-1)*(tc.string[tc.strings[c]]?-1:1)}else{dir=tc.strings[c]?tc.string[tc.strings[c]]||0:0}}dynamicExp+="var "+e+" = sort"+s+"(table, a["+c+"],b["+c+"],"+c+","+mx+","+dir+"); ";dynamicExp+="if ("+e+") { return "+e+"; } ";dynamicExp+="else { "}orgOrderCol=cache.normalized&&cache.normalized[0]?cache.normalized[0].length-1:0;dynamicExp+="return a["+orgOrderCol+"]-b["+orgOrderCol+"];";for(i=0;i<l;i++){dynamicExp+="}; "}dynamicExp+="return 0; ";dynamicExp+="}; ";eval(dynamicExp);cache.normalized.sort(sortWrapper)}if(tc.debug){benchmark("Sorting on "+sortList.toString()+" and dir "+order+" time",sortTime)}}function sortText(a,b,c,d){if(b===c){return 0}var e=a.config,f=e.string[e.empties[d]||e.emptyTo],g=$.tablesorter.regex,h,i,j,k,l,m,n,o;if(b===""&&f!==0){return typeof f==="boolean"?f?-1:1:-f||-1}if(c===""&&f!==0){return typeof f==="boolean"?f?1:-1:f||1}if(typeof e.textSorter==="function"){return e.textSorter(b,c,a,d)}h=b.replace(g[0],"\0$1\0").replace(/\0$/,"").replace(/^\0/,"").split("\0");j=c.replace(g[0],"\0$1\0").replace(/\0$/,"").replace(/^\0/,"").split("\0");i=parseInt(b.match(g[2]))||h.length!==1&&b.match(g[1])&&Date.parse(b);k=parseInt(c.match(g[2]))||i&&c.match(g[1])&&Date.parse(c)||null;if(k){if(i<k){return-1}if(i>k){return 1}}o=Math.max(h.length,j.length);for(n=0;n<o;n++){l=!(h[n]||"").match(g[3])&&parseFloat(h[n])||h[n]||0;m=!(j[n]||"").match(g[3])&&parseFloat(j[n])||j[n]||0;if(isNaN(l)!==isNaN(m)){return isNaN(l)?1:-1}if(typeof l!==typeof m){l+="";m+=""}if(l<m){return-1}if(l>m){return 1}}return 0}function sortTextDesc(a,b,c,d){if(b===c){return 0}var e=a.config,f=e.string[e.empties[d]||e.emptyTo];if(b===""&&f!==0){return typeof f==="boolean"?f?-1:1:f||1}if(c===""&&f!==0){return typeof f==="boolean"?f?1:-1:-f||-1}if(typeof e.textSorter==="function"){return e.textSorter(c,b,a,d)}return sortText(a,c,b)}function getTextValue(a,b,c){if(b){var d,e=a.length,f=b+c;for(d=0;d<e;d++){f+=a.charCodeAt(d)}return c*f}return 0}function sortNumeric(a,b,c,d,e,f){if(b===c){return 0}var g=a.config,h=g.string[g.empties[d]||g.emptyTo];if(b===""&&h!==0){return typeof h==="boolean"?h?-1:1:-h||-1}if(c===""&&h!==0){return typeof h==="boolean"?h?1:-1:h||1}if(isNaN(b)){b=getTextValue(b,e,f)}if(isNaN(c)){c=getTextValue(c,e,f)}return b-c}function sortNumericDesc(a,b,c,d,e,f){if(b===c){return 0}var g=a.config,h=g.string[g.empties[d]||g.emptyTo];if(b===""&&h!==0){return typeof h==="boolean"?h?-1:1:h||1}if(c===""&&h!==0){return typeof h==="boolean"?h?1:-1:-h||-1}if(isNaN(b)){b=getTextValue(b,e,f)}if(isNaN(c)){c=getTextValue(c,e,f)}return c-b}this.version="2.3.5";var parsers=[],widgets=[];this.defaults={widthFixed:false,cancelSelection:true,dateFormat:"mmddyyyy",sortMultiSortKey:"shiftKey",usNumberFormat:true,delayInit:false,headers:{},ignoreCase:true,sortForce:null,sortList:[],sortAppend:null,sortInitialOrder:"asc",sortLocaleCompare:false,sortReset:false,sortRestart:false,emptyTo:"bottom",stringTo:"max",textExtraction:"simple",textSorter:null,widgets:[],widgetOptions:{zebra:["even","odd"]},initWidgets:true,initialized:null,onRenderHeader:null,tableClass:"tablesorter",cssAsc:"tablesorter-headerSortUp",cssChildRow:"expand-child",cssDesc:"tablesorter-headerSortDown",cssHeader:"tablesorter-header",cssInfoBlock:"tablesorter-infoOnly",selectorHeaders:"> thead th",selectorRemove:"tr.remove-me",debug:false,headerList:[],empties:{},strings:{},parsers:[]};this.benchmark=benchmark;this.hasInitialized=false;this.construct=function(a){return this.each(function(){if(!this.tHead||this.tBodies.length===0){return}var b,c,d,e,f,g,h,i,j,k,l,m,n=$.metadata;this.config={};f=e=$.extend(true,this.config,$.tablesorter.defaults,a);if(f.debug){$.data(this,"startoveralltimer",new Date)}d=$(this).addClass(f.tableClass);$.data(this,"tablesorter",f);f.supportsTextContent=$("<span>x</span>")[0].textContent==="x";buildRegex();f.string={max:1,min:-1,"max+":1,"max-":-1,zero:0,none:0,"null":0,top:true,bottom:false};b=buildHeaders(this);f.parsers=buildParserCache(this,b);if(!f.delayInit){buildCache(this)}fixColumnWidth(this);b.bind("mousedown.tablesorter mouseup.tablesorter",function(a,e){if(a.type==="mousedown"){m=(new Date).getTime();return!f.cancelSelection}if(e!==true&&(new Date).getTime()-m>500){return false}if(f.delayInit&&!f.cache){buildCache(d[0])}if(!this.sortDisabled){d.trigger("sortStart",d[0]);c=$(this);i=!a[f.sortMultiSortKey];this.count=(this.count+1)%(f.sortReset?3:2);if(f.sortRestart){g=this;b.each(function(){if(this!==g&&(i||!$(this).is("."+f.cssDesc+",."+f.cssAsc))){this.count=-1}})}g=this.column;if(i){f.sortList=[];if(f.sortForce!==null){j=f.sortForce;for(h=0;h<j.length;h++){if(j[h][0]!==g){f.sortList.push(j[h])}}}l=this.order[this.count];if(l<2){f.sortList.push([g,l]);if(this.colSpan>1){for(h=1;h<this.colSpan;h++){f.sortList.push([g+h,l])}}}}else{if(isValueInArray(g,f.sortList)){for(h=0;h<f.sortList.length;h++){k=f.sortList[h];l=f.headerList[k[0]];if(k[0]===g){k[1]=l.order[l.count];if(k[1]===2){f.sortList.splice(h,1);l.count=-1}}}}else{l=this.order[this.count];if(l<2){f.sortList.push([g,l]);if(this.colSpan>1){for(h=1;h<this.colSpan;h++){f.sortList.push([g+h,l])}}}}}if(f.sortAppend!==null){j=f.sortAppend;for(h=0;h<j.length;h++){if(j[h][0]!==g){f.sortList.push(j[h])}}}d.trigger("sortBegin",d[0]);setHeadersCss(d[0],b,f.sortList);multisort(d[0],f.sortList);appendToTable(d[0]);return false}});if(f.cancelSelection){b.each(function(){this.onselectstart=function(){return false}})}d.bind("update",function(a,c){$(f.selectorRemove,this).remove();f.parsers=buildParserCache(this,b);buildCache(this);if(c!==false){$(this).trigger("sorton",[f.sortList])}}).bind("updateCell",function(a,b,c){var d=this,e=[b.parentNode.rowIndex-1,b.cellIndex],g=$(this).find("tbody").index($(b).closest("tbody"));d.config.cache[g].normalized[e[0]][e[1]]=f.parsers[e[1]].format(getElementText(d,b,e[1]),d,b,e[1]);if(c!==false){$(this).trigger("sorton",[f.sortList])}}).bind("addRows",function(a,b,c){var d,e=b.filter("tr").length,g=[],i=b[0].cells.length,j=this,k=$(this).find("tbody").index(b.closest("tbody"));for(d=0;d<e;d++){for(h=0;h<i;h++){g[h]=f.parsers[h].format(getElementText(j,b[d].cells[h],h),j,b[d].cells[h],h)}g.push(f.cache[k].row.length);f.cache[k].row.push([b[d]]);f.cache[k].normalized.push(g);g=[]}if(c!==false){$(this).trigger("sorton",[f.sortList])}}).bind("sorton",function(a,c,d){$(this).trigger("sortStart",this);f.sortList=c;updateHeaderSortCount(this,f.sortList);setHeadersCss(this,b,f.sortList);multisort(this,f.sortList);appendToTable(this,d)}).bind("appendCache",function(a,b){appendToTable(this,b)}).bind("applyWidgetId",function(a,b){getWidgetById(b).format(this)}).bind("applyWidgets",function(a,b){applyWidget(this,b)}).bind("destroy",function(a,b){$.tablesorter.destroy(this,b)});if(d.data()&&typeof d.data().sortlist!=="undefined"){f.sortList=d.data().sortlist}else if(n&&d.metadata()&&d.metadata().sortlist){f.sortList=d.metadata().sortlist}applyWidget(this,true);if(f.sortList.length>0){d.trigger("sorton",[f.sortList,!f.initWidgets])}else if(f.initWidgets){applyWidget(this)}this.hasInitialized=true;if(f.debug){$.tablesorter.benchmark("Overall initialization time",$.data(this,"startoveralltimer"))}d.trigger("tablesorter-initialized",this);if(typeof f.initialized==="function"){f.initialized(this)}})};this.destroy=function(a,b){var c=$(a),d=a.config;c.find("thead:first tr:not(."+d.cssHeader+")").remove();c.find("thead:first .tablesorter-resizer").remove();c.unbind("update updateCell addRows sorton appendCache applyWidgetId applyWidgets destroy mouseup mouseleave").find(d.selectorHeaders).unbind("click mousedown mousemove mouseup").removeClass(d.cssHeader+" "+d.cssAsc+" "+d.cssDesc);if(b!==false){c.removeClass(d.tableClass)}};this.addParser=function(a){var b,c=parsers.length,d=true;for(b=0;b<c;b++){if(parsers[b].id.toLowerCase()===a.id.toLowerCase()){d=false}}if(d){parsers.push(a)}};this.addWidget=function(a){widgets.push(a)};this.formatFloat=function(a,b){if(typeof a!=="string"||a===""){return a}if(b.config.usNumberFormat!==false){a=a.replace(/,/g,"")}else{a=a.replace(/[\s|\.]/g,"").replace(/,/g,".")}if(/^\s*\([.\d]+\)/.test(a)){a=a.replace(/^\s*\(/,"-").replace(/\)/,"")}var c=parseFloat(a);return isNaN(c)?$.trim(a):c};this.isDigit=function(a){return/^[\-+(]?\d*[)]?$/.test(a.replace(/[,.'\s]/g,""))};this.regex=[/(^-?[0-9]+(\.?[0-9]*)[df]?e?[0-9]?$|^0x[0-9a-f]+$|[0-9]+)/gi,/(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/,/^0x[0-9a-f]+$/i,/^0/];this.characterEquivalents={a:"áàâãä",A:"ÁÀÂÃÄ",c:"ç",C:"Ç",e:"éèêë",E:"ÉÈÊË",i:"íìIîï",I:"ÍÌIÎÏ",o:"óòôõö",O:"ÓÒÔÕÖ",S:"ß",u:"úùûü",U:"ÚÙÛÜ"};this.replaceAccents=function(a){if(this.characterRegex.test(a)){var b,c=this.characterEquivalents;for(b in c){if(typeof b==="string"){a=a.replace(this.characterRegexArray[b],b)}}}return a};this.getData=function(a,b,c){var d="",e=$(a),f,g;if(!e.length){return""}f=$.metadata?e.metadata():false;g=" "+(e.attr("class")||"");if(e.data()&&(typeof e.data(c)!=="undefined"||typeof e.data(c.toLowerCase())!=="undefined")){d+=e.data(c)||e.data(c.toLowerCase())}else if(f&&typeof f[c]!=="undefined"){d+=f[c]}else if(b&&typeof b[c]!=="undefined"){d+=b[c]}else if(g&&g.match(" "+c+"-")){d=g.match(new RegExp(" "+c+"-(\\w+)"))[1]||""}return $.trim(d)};this.clearTableBody=function(a){$(a.tBodies).filter(":not(."+a.config.cssInfoBlock+")").empty()}}})();var ts=$.tablesorter;$.fn.extend({tablesorter:ts.construct});ts.addParser({id:"text",is:function(a,b,c){return true},format:function(a,b,c,d){var e=b.config;a=$.trim(e.ignoreCase?a.toLocaleLowerCase():a);return e.sortLocaleCompare?ts.replaceAccents(a):a},type:"text"});ts.addParser({id:"currency",is:function(a){return/^\(?[\u00a3$\u20ac\u00a4\u00a5\u00a2?.]\d+/.test(a)},format:function(a,b){return ts.formatFloat(a.replace(/[^\w,. \-()]/g,""),b)},type:"numeric"});ts.addParser({id:"ipAddress",is:function(a){return/^\d{2,3}[\.]\d{2,3}[\.]\d{2,3}[\.]\d{2,3}$/.test(a)},format:function(a,b){var c,d,e=a.split("."),f="",g=e.length;for(c=0;c<g;c++){d=e[c];if(d.length===2){f+="0"+d}else{f+=d}}return ts.formatFloat(f,b)},type:"numeric"});ts.addParser({id:"url",is:function(a){return/^(https?|ftp|file):\/\/$/.test(a)},format:function(a){return $.trim(a.replace(/(https?|ftp|file):\/\//,""))},type:"text"});ts.addParser({id:"isoDate",is:function(a){return/^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}$/.test(a)},format:function(a,b){return ts.formatFloat(a!==""?(new Date(a.replace(/-/g,"/"))).getTime()||"":"",b)},type:"numeric"});ts.addParser({id:"percent",is:function(a){return/\d%\)?$/.test(a)},format:function(a,b){return ts.formatFloat(a.replace(/%/g,""),b)},type:"numeric"});ts.addParser({id:"usLongDate",is:function(a){return a.match(/^[A-Za-z]{3,10}\.? [0-9]{1,2}, ([0-9]{4}|'?[0-9]{2}) (([0-2]?[0-9]:[0-5][0-9])|([0-1]?[0-9]:[0-5][0-9]\s(AM|PM)))$/)},format:function(a,b){return ts.formatFloat((new Date(a)).getTime()||"",b)},type:"numeric"});ts.addParser({id:"shortDate",is:function(a){return/^(\d{2}|\d{4})[\/\-\,\.\s+]\d{2}[\/\-\.\,\s+](\d{2}|\d{4})$/.test(a)},format:function(a,b,c,d){var e=b.config,f=e.headerList[d],g=f.shortDateFormat;if(typeof g==="undefined"){g=f.shortDateFormat=ts.getData(f,e.headers[d],"dateFormat")||e.dateFormat}a=a.replace(/\s+/g," ").replace(/[\-|\.|\,]/g,"/");if(g==="mmddyyyy"){a=a.replace(/(\d{1,2})[\/\s](\d{1,2})[\/\s](\d{4})/,"$3/$1/$2")}else if(g==="ddmmyyyy"){a=a.replace(/(\d{1,2})[\/\s](\d{1,2})[\/\s](\d{4})/,"$3/$2/$1")}else if(g==="yyyymmdd"){a=a.replace(/(\d{4})[\/\s](\d{1,2})[\/\s](\d{1,2})/,"$1/$2/$3")}return ts.formatFloat((new Date(a)).getTime()||"",b)},type:"numeric"});ts.addParser({id:"time",is:function(a){return/^(([0-2]?[0-9]:[0-5][0-9])|([0-1]?[0-9]:[0-5][0-9]\s(am|pm)))$/.test(a)},format:function(a,b){return ts.formatFloat((new Date("2000/01/01 "+a)).getTime()||"",b)},type:"numeric"});ts.addParser({id:"digit",is:function(a){return ts.isDigit(a)},format:function(a,b){return ts.formatFloat(a.replace(/[^\w,. \-()]/g,""),b)},type:"numeric"});ts.addParser({id:"metadata",is:function(a){return false},format:function(a,b,c){var d=b.config,e=!d.parserMetadataName?"sortValue":d.parserMetadataName;return $(c).metadata()[e]},type:"numeric"});ts.addWidget({id:"zebra",format:function(a){var b,c,d,e,f,g,h,i,j=a.config,k=new RegExp(j.cssChildRow,"i"),l=$(a).children("tbody:not(."+j.cssInfoBlock+")"),m=["even","odd"];m=j.widgetZebra&&j.hasOwnProperty("css")?j.widgetZebra.css:j.widgetOptions&&j.widgetOptions.hasOwnProperty("zebra")?j.widgetOptions.zebra:m;if(j.debug){g=new Date}for(h=0;h<l.length;h++){b=$(l[h]);i=b.children("tr").length;if(i>1){e=0;c=b.find("tr:visible");b.addClass("tablesorter-hidden");c.each(function(){d=$(this);if(!k.test(this.className)){e++}f=e%2===0;d.removeClass(m[f?1:0]).addClass(m[f?0:1])});b.removeClass("tablesorter-hidden")}}if(j.debug){ts.benchmark("Applying Zebra widget",g)}}})}(jQuery)
+!function($){$.extend({tablesorter:new function(){function log(a){if(typeof console!=="undefined"&&typeof console.log!=="undefined"){console.log(a)}else{alert(a)}}function benchmark(a,b){log(a+" ("+((new Date).getTime()-b.getTime())+"ms)")}function getElementText(a,b,c){if(!b){return""}var d=a.config,e=d.textExtraction,f="";if(e==="simple"){if(d.supportsTextContent){f=b.textContent}else{if(b.childNodes[0]&&b.childNodes[0].hasChildNodes()){f=b.childNodes[0].innerHTML}else{f=b.innerHTML}}}else{if(typeof e==="function"){f=e(b,a,c)}else if(typeof e==="object"&&e.hasOwnProperty(c)){f=e[c](b,a,c)}else{f=d.supportsTextContent?b.textContent:$(b).text()}}return $.trim(f)}function getParserById(a){var b,c=parsers.length;for(b=0;b<c;b++){if(parsers[b].id.toLowerCase()===a.toString().toLowerCase()){return parsers[b]}}return false}function detectParserForColumn(a,b,c,d){var e,f=parsers.length,g=false,h="",i=true;while(h===""&&i){c++;if(b[c]){g=b[c].cells[d];h=getElementText(a,g,d);if(a.config.debug){log("Checking if value was empty on row "+c+", column: "+d+": "+h)}}else{i=false}}for(e=1;e<f;e++){if(parsers[e].is(h,a,g)){return parsers[e]}}return parsers[0]}function buildParserCache(a,b){var c=a.config,d=$(a.tBodies).filter(":not(."+c.cssInfoBlock+")"),e=$.tablesorter,f,g,h,i,j,k,l,m,n,o="";if(d.length===0){return}f=d[0].rows;if(f[0]){g=[];h=f[0].cells.length;for(i=0;i<h;i++){j=b.filter(':not([colspan])[data-column="'+i+'"]:last,[colspan="1"][data-column="'+i+'"]:last');l=c.headers[i];n=getParserById(e.getData(j,l,"sorter"));c.empties[i]=e.getData(j,l,"empty")||c.emptyTo||(c.emptyToBottom?"bottom":"top");c.strings[i]=e.getData(j,l,"string")||c.stringTo||"max";if(!n){n=detectParserForColumn(a,f,-1,i)}if(c.debug){o+="column:"+i+"; parser:"+n.id+"; string:"+c.strings[i]+"; empty: "+c.empties[i]+"\n"}g.push(n)}}if(c.debug){log(o)}return g}function buildRegex(){var a,b="[",c=$.tablesorter,d=c.characterEquivalents;c.characterRegexArray={};for(a in d){if(typeof a==="string"){b+=d[a];c.characterRegexArray[a]=new RegExp("["+d[a]+"]","g")}}c.characterRegex=new RegExp(b+"]")}function buildCache(a){var b=a.tBodies,c=a.config,d,e,f=c.parsers,g,h,i,j,k,l,m;c.cache={};if(c.debug){m=new Date}for(j=0;j<b.length;j++){c.cache[j]={row:[],normalized:[]};if(!$(b[j]).hasClass(c.cssInfoBlock)){$(b[j]).addClass("tablesorter-hidden");d=b[j]&&b[j].rows.length||0;e=b[j].rows[0]&&b[j].rows[0].cells.length||0;for(h=0;h<d;++h){k=$(b[j].rows[h]);l=[];if(k.hasClass(c.cssChildRow)){c.cache[j].row[c.cache[j].row.length-1]=c.cache[j].row[c.cache[j].row.length-1].add(k);continue}c.cache[j].row.push(k);for(i=0;i<e;++i){g=getElementText(a,k[0].cells[i],i);l.push(f[i].format(g,a,k[0].cells[i],i))}l.push(c.cache[j].normalized.length);c.cache[j].normalized.push(l)}$(b[j]).removeClass("tablesorter-hidden")}}if(c.debug){benchmark("Building cache for "+d+" rows",m)}}function getWidgetById(a){var b,c,d=widgets.length;for(b=0;b<d;b++){c=widgets[b];if(c&&c.hasOwnProperty("id")&&c.id.toLowerCase()===a.toLowerCase()){return c}}}function applyWidget(a,b){var c=a.config,d=c.widgets,e,f,g,h=d.length;if(c.debug){e=new Date}for(f=0;f<h;f++){g=getWidgetById(d[f]);if(g){if(b===true&&g.hasOwnProperty("init")){g.init(a,widgets,g)}else if(!b&&g.hasOwnProperty("format")){g.format(a)}}}if(c.debug){benchmark("Completed "+(b===true?"initializing":"applying")+" widgets",e)}}function appendToTable(a,b){var c=a.config,d=a.tBodies,e=[],f,g,h,i,j=c.cache,k,l,m,n,o,p,q;if(c.debug){q=new Date}for(n=0;n<d.length;n++){if(!$(d[n]).hasClass(c.cssInfoBlock)){$(d[n]).addClass("tablesorter-hidden");k=document.createDocumentFragment();f=j[n].row;g=j[n].normalized;h=g.length;i=h?g[0].length-1:0;for(l=0;l<h;l++){p=g[l][i];e.push(f[p]);if(!c.appender||!c.removeRows){o=f[p].length;for(m=0;m<o;m++){k.appendChild(f[p][m])}}}a.tBodies[n].appendChild(k);$(d[n]).removeClass("tablesorter-hidden")}}if(c.appender){c.appender(a,e)}if(c.debug){benchmark("Rebuilt table",q)}if(!b){applyWidget(a)}$(a).trigger("sortEnd",a)}function computeThIndexes(a){var b=[],c={},d=$(a).find("thead:eq(0) tr"),e,f,g,h,i,j,k,l,m,n,o,p;for(e=0;e<d.length;e++){j=d[e].cells;for(f=0;f<j.length;f++){i=j[f];k=i.parentNode.rowIndex;l=k+"-"+i.cellIndex;m=i.rowSpan||1;n=i.colSpan||1;if(typeof b[k]==="undefined"){b[k]=[]}for(g=0;g<b[k].length+1;g++){if(typeof b[k][g]==="undefined"){o=g;break}}c[l]=o;$(i).attr({"data-column":o});for(g=k;g<k+m;g++){if(typeof b[g]==="undefined"){b[g]=[]}p=b[g];for(h=o;h<o+n;h++){p[h]="x"}}}}return c}function formatSortingOrder(a){return/^d/i.test(a)||a===1}function buildHeaders(a){var b=computeThIndexes(a),c,d,e,f,g,h,i=a.config,j=$.tablesorter;i.headerList=[];if(i.debug){g=new Date}h=$(a).find(i.selectorHeaders).each(function(a){d=$(this);c=i.headers[a];this.innerHTML='<div class="tablesorter-header-inner">'+this.innerHTML+"</div>";if(i.onRenderHeader){i.onRenderHeader.apply(e,[a])}this.column=b[this.parentNode.rowIndex+"-"+this.cellIndex];this.order=formatSortingOrder(j.getData(d,c,"sortInitialOrder")||i.sortInitialOrder)?[1,0,2]:[0,1,2];this.count=-1;if(j.getData(d,c,"sorter")==="false"){this.sortDisabled=true}this.lockedOrder=false;f=j.getData(d,c,"lockedOrder")||false;if(typeof f!=="undefined"&&f!==false){this.order=this.lockedOrder=formatSortingOrder(f)?[1,1,1]:[0,0,0]}if(!this.sortDisabled){e=d.addClass(i.cssHeader)}i.headerList[a]=this;d.parent().addClass(i.cssHeader)});if(a.config.debug){benchmark("Built headers:",g);log(h)}return h}function isValueInArray(a,b){var c,d=b.length;for(c=0;c<d;c++){if(b[c][0]===a){return true}}return false}function setHeadersCss(a,b,c){var d,e=[],f,g,h,i=[a.config.cssDesc,a.config.cssAsc];b.removeClass(i.join(" ")).each(function(){if(!this.sortDisabled){e[this.column]=$(this)}});h=c.length;for(f=0;f<h;f++){if(c[f][1]===2){continue}if(e[c[f][0]]){e[c[f][0]].addClass(i[c[f][1]])}d=b.filter('[data-column="'+c[f][0]+'"]');if(h>1&&d.length){for(g=0;g<d.length;g++){if(!d[g].sortDisabled){$(d[g]).addClass(i[c[f][1]])}}}}}function fixColumnWidth(a){if(a.config.widthFixed){var b=$("<colgroup>");$("tr:first td",a.tBodies[0]).each(function(){b.append($("<col>").css("width",$(this).width()))});$(a).prepend(b)}}function updateHeaderSortCount(a,b){var c,d,e,f=a.config,g=b.length;for(c=0;c<g;c++){d=b[c];e=f.headerList[d[0]];e.count=d[1]%(f.sortReset?3:2)}}function getCachedSortType(a,b){return a&&a[b]?a[b].type||"":""}function multisort(table,sortList){var dynamicExp,col,mx=0,dir=0,tc=table.config,l=sortList.length,bl=table.tBodies.length,sortTime,i,j,k,c,cache,lc,s,e,order,orgOrderCol;if(tc.debug){sortTime=new Date}for(k=0;k<bl;k++){dynamicExp="var sortWrapper = function(a,b) {";cache=tc.cache[k];lc=cache.normalized.length;for(i=0;i<l;i++){c=sortList[i][0];order=sortList[i][1];s=/n/i.test(getCachedSortType(tc.parsers,c))?"Numeric":"Text";s+=order===0?"":"Desc";e="e"+i;if(/Numeric/.test(s)&&tc.strings[c]){for(j=0;j<lc;j++){col=Math.abs(parseFloat(cache.normalized[j][c]));mx=Math.max(mx,isNaN(col)?0:col)}if(typeof tc.string[tc.strings[c]]==="boolean"){dir=(order===0?1:-1)*(tc.string[tc.strings[c]]?-1:1)}else{dir=tc.strings[c]?tc.string[tc.strings[c]]||0:0}}dynamicExp+="var "+e+" = sort"+s+"(table, a["+c+"],b["+c+"],"+c+","+mx+","+dir+"); ";dynamicExp+="if ("+e+") { return "+e+"; } ";dynamicExp+="else { "}orgOrderCol=cache.normalized&&cache.normalized[0]?cache.normalized[0].length-1:0;dynamicExp+="return a["+orgOrderCol+"]-b["+orgOrderCol+"];";for(i=0;i<l;i++){dynamicExp+="}; "}dynamicExp+="return 0; ";dynamicExp+="}; ";eval(dynamicExp);cache.normalized.sort(sortWrapper)}if(tc.debug){benchmark("Sorting on "+sortList.toString()+" and dir "+order+" time",sortTime)}}function sortText(a,b,c,d){if(b===c){return 0}var e=a.config,f=e.string[e.empties[d]||e.emptyTo],g=$.tablesorter.regex,h,i,j,k,l,m,n,o;if(b===""&&f!==0){return typeof f==="boolean"?f?-1:1:-f||-1}if(c===""&&f!==0){return typeof f==="boolean"?f?1:-1:f||1}if(typeof e.textSorter==="function"){return e.textSorter(b,c,a,d)}h=b.replace(g[0],"\0$1\0").replace(/\0$/,"").replace(/^\0/,"").split("\0");j=c.replace(g[0],"\0$1\0").replace(/\0$/,"").replace(/^\0/,"").split("\0");i=parseInt(b.match(g[2]))||h.length!==1&&b.match(g[1])&&Date.parse(b);k=parseInt(c.match(g[2]))||i&&c.match(g[1])&&Date.parse(c)||null;if(k){if(i<k){return-1}if(i>k){return 1}}o=Math.max(h.length,j.length);for(n=0;n<o;n++){l=!(h[n]||"").match(g[3])&&parseFloat(h[n])||h[n]||0;m=!(j[n]||"").match(g[3])&&parseFloat(j[n])||j[n]||0;if(isNaN(l)!==isNaN(m)){return isNaN(l)?1:-1}if(typeof l!==typeof m){l+="";m+=""}if(l<m){return-1}if(l>m){return 1}}return 0}function sortTextDesc(a,b,c,d){if(b===c){return 0}var e=a.config,f=e.string[e.empties[d]||e.emptyTo];if(b===""&&f!==0){return typeof f==="boolean"?f?-1:1:f||1}if(c===""&&f!==0){return typeof f==="boolean"?f?1:-1:-f||-1}if(typeof e.textSorter==="function"){return e.textSorter(c,b,a,d)}return sortText(a,c,b)}function getTextValue(a,b,c){if(b){var d,e=a.length,f=b+c;for(d=0;d<e;d++){f+=a.charCodeAt(d)}return c*f}return 0}function sortNumeric(a,b,c,d,e,f){if(b===c){return 0}var g=a.config,h=g.string[g.empties[d]||g.emptyTo];if(b===""&&h!==0){return typeof h==="boolean"?h?-1:1:-h||-1}if(c===""&&h!==0){return typeof h==="boolean"?h?1:-1:h||1}if(isNaN(b)){b=getTextValue(b,e,f)}if(isNaN(c)){c=getTextValue(c,e,f)}return b-c}function sortNumericDesc(a,b,c,d,e,f){if(b===c){return 0}var g=a.config,h=g.string[g.empties[d]||g.emptyTo];if(b===""&&h!==0){return typeof h==="boolean"?h?-1:1:h||1}if(c===""&&h!==0){return typeof h==="boolean"?h?1:-1:-h||-1}if(isNaN(b)){b=getTextValue(b,e,f)}if(isNaN(c)){c=getTextValue(c,e,f)}return c-b}this.version="2.3.6";var parsers=[],widgets=[];this.defaults={widthFixed:false,cancelSelection:true,dateFormat:"mmddyyyy",sortMultiSortKey:"shiftKey",usNumberFormat:true,delayInit:false,headers:{},ignoreCase:true,sortForce:null,sortList:[],sortAppend:null,sortInitialOrder:"asc",sortLocaleCompare:false,sortReset:false,sortRestart:false,emptyTo:"bottom",stringTo:"max",textExtraction:"simple",textSorter:null,widgets:[],widgetOptions:{zebra:["even","odd"]},initWidgets:true,initialized:null,onRenderHeader:null,tableClass:"tablesorter",cssAsc:"tablesorter-headerSortUp",cssChildRow:"expand-child",cssDesc:"tablesorter-headerSortDown",cssHeader:"tablesorter-header",cssInfoBlock:"tablesorter-infoOnly",selectorHeaders:"> thead th",selectorRemove:"tr.remove-me",debug:false,headerList:[],empties:{},strings:{},parsers:[]};this.benchmark=benchmark;this.hasInitialized=false;this.construct=function(a){return this.each(function(){if(!this.tHead||this.tBodies.length===0){return}var b,c,d,e,f,g,h,i,j,k,l,m,n=$.metadata;this.config={};f=e=$.extend(true,this.config,$.tablesorter.defaults,a);if(f.debug){$.data(this,"startoveralltimer",new Date)}d=$(this).addClass(f.tableClass);$.data(this,"tablesorter",f);f.supportsTextContent=$("<span>x</span>")[0].textContent==="x";buildRegex();f.string={max:1,min:-1,"max+":1,"max-":-1,zero:0,none:0,"null":0,top:true,bottom:false};b=buildHeaders(this);f.parsers=buildParserCache(this,b);if(!f.delayInit){buildCache(this)}fixColumnWidth(this);b.bind("mousedown.tablesorter mouseup.tablesorter",function(a,e){if(a.type==="mousedown"){m=(new Date).getTime();return!f.cancelSelection}if(e!==true&&(new Date).getTime()-m>500){return false}if(f.delayInit&&!f.cache){buildCache(d[0])}if(!this.sortDisabled){d.trigger("sortStart",d[0]);c=$(this);i=!a[f.sortMultiSortKey];this.count=(this.count+1)%(f.sortReset?3:2);if(f.sortRestart){g=this;b.each(function(){if(this!==g&&(i||!$(this).is("."+f.cssDesc+",."+f.cssAsc))){this.count=-1}})}g=this.column;if(i){f.sortList=[];if(f.sortForce!==null){j=f.sortForce;for(h=0;h<j.length;h++){if(j[h][0]!==g){f.sortList.push(j[h])}}}l=this.order[this.count];if(l<2){f.sortList.push([g,l]);if(this.colSpan>1){for(h=1;h<this.colSpan;h++){f.sortList.push([g+h,l])}}}}else{if(isValueInArray(g,f.sortList)){for(h=0;h<f.sortList.length;h++){k=f.sortList[h];l=f.headerList[k[0]];if(k[0]===g){k[1]=l.order[l.count];if(k[1]===2){f.sortList.splice(h,1);l.count=-1}}}}else{l=this.order[this.count];if(l<2){f.sortList.push([g,l]);if(this.colSpan>1){for(h=1;h<this.colSpan;h++){f.sortList.push([g+h,l])}}}}}if(f.sortAppend!==null){j=f.sortAppend;for(h=0;h<j.length;h++){if(j[h][0]!==g){f.sortList.push(j[h])}}}d.trigger("sortBegin",d[0]);setHeadersCss(d[0],b,f.sortList);multisort(d[0],f.sortList);appendToTable(d[0]);return false}});if(f.cancelSelection){b.each(function(){this.onselectstart=function(){return false}})}d.bind("update",function(a,c){$(f.selectorRemove,this).remove();f.parsers=buildParserCache(this,b);buildCache(this);if(c!==false){$(this).trigger("sorton",[f.sortList])}}).bind("updateCell",function(a,b,c){var d=this,e=[b.parentNode.rowIndex-1,b.cellIndex],g=$(this).find("tbody").index($(b).closest("tbody"));d.config.cache[g].normalized[e[0]][e[1]]=f.parsers[e[1]].format(getElementText(d,b,e[1]),d,b,e[1]);if(c!==false){$(this).trigger("sorton",[f.sortList])}}).bind("addRows",function(a,b,c){var d,e=b.filter("tr").length,g=[],i=b[0].cells.length,j=this,k=$(this).find("tbody").index(b.closest("tbody"));for(d=0;d<e;d++){for(h=0;h<i;h++){g[h]=f.parsers[h].format(getElementText(j,b[d].cells[h],h),j,b[d].cells[h],h)}g.push(f.cache[k].row.length);f.cache[k].row.push([b[d]]);f.cache[k].normalized.push(g);g=[]}if(c!==false){$(this).trigger("sorton",[f.sortList])}}).bind("sorton",function(a,c,d){$(this).trigger("sortStart",this);f.sortList=c;updateHeaderSortCount(this,f.sortList);setHeadersCss(this,b,f.sortList);multisort(this,f.sortList);appendToTable(this,d)}).bind("appendCache",function(a,b){appendToTable(this,b)}).bind("applyWidgetId",function(a,b){getWidgetById(b).format(this)}).bind("applyWidgets",function(a,b){applyWidget(this,b)}).bind("destroy",function(a,b){$.tablesorter.destroy(this,b)});if(d.data()&&typeof d.data().sortlist!=="undefined"){f.sortList=d.data().sortlist}else if(n&&d.metadata()&&d.metadata().sortlist){f.sortList=d.metadata().sortlist}applyWidget(this,true);if(f.sortList.length>0){d.trigger("sorton",[f.sortList,!f.initWidgets])}else if(f.initWidgets){applyWidget(this)}this.hasInitialized=true;if(f.debug){$.tablesorter.benchmark("Overall initialization time",$.data(this,"startoveralltimer"))}d.trigger("tablesorter-initialized",this);if(typeof f.initialized==="function"){f.initialized(this)}})};this.destroy=function(a,b){var c=$(a),d=a.config;c.find("thead:first tr:not(."+d.cssHeader+")").remove();c.find("thead:first .tablesorter-resizer").remove();c.unbind("update updateCell addRows sorton appendCache applyWidgetId applyWidgets destroy mouseup mouseleave").find(d.selectorHeaders).unbind("click mousedown mousemove mouseup").removeClass(d.cssHeader+" "+d.cssAsc+" "+d.cssDesc);if(b!==false){c.removeClass(d.tableClass)}};this.addParser=function(a){var b,c=parsers.length,d=true;for(b=0;b<c;b++){if(parsers[b].id.toLowerCase()===a.id.toLowerCase()){d=false}}if(d){parsers.push(a)}};this.addWidget=function(a){widgets.push(a)};this.formatFloat=function(a,b){if(typeof a!=="string"||a===""){return a}if(b.config.usNumberFormat!==false){a=a.replace(/,/g,"")}else{a=a.replace(/[\s|\.]/g,"").replace(/,/g,".")}if(/^\s*\([.\d]+\)/.test(a)){a=a.replace(/^\s*\(/,"-").replace(/\)/,"")}var c=parseFloat(a);return isNaN(c)?$.trim(a):c};this.isDigit=function(a){return/^[\-+(]?\d*[)]?$/.test(a.replace(/[,.'\s]/g,""))};this.regex=[/(^-?[0-9]+(\.?[0-9]*)[df]?e?[0-9]?$|^0x[0-9a-f]+$|[0-9]+)/gi,/(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/,/^0x[0-9a-f]+$/i,/^0/];this.characterEquivalents={a:"áàâãä",A:"ÁÀÂÃÄ",c:"ç",C:"Ç",e:"éèêë",E:"ÉÈÊË",i:"íìIîï",I:"ÍÌIÎÏ",o:"óòôõö",O:"ÓÒÔÕÖ",S:"ß",u:"úùûü",U:"ÚÙÛÜ"};this.replaceAccents=function(a){if(this.characterRegex.test(a)){var b,c=this.characterEquivalents;for(b in c){if(typeof b==="string"){a=a.replace(this.characterRegexArray[b],b)}}}return a};this.getData=function(a,b,c){var d="",e=$(a),f,g;if(!e.length){return""}f=$.metadata?e.metadata():false;g=" "+(e.attr("class")||"");if(e.data()&&(typeof e.data(c)!=="undefined"||typeof e.data(c.toLowerCase())!=="undefined")){d+=e.data(c)||e.data(c.toLowerCase())}else if(f&&typeof f[c]!=="undefined"){d+=f[c]}else if(b&&typeof b[c]!=="undefined"){d+=b[c]}else if(g&&g.match(" "+c+"-")){d=g.match(new RegExp(" "+c+"-(\\w+)"))[1]||""}return $.trim(d)};this.clearTableBody=function(a){$(a.tBodies).filter(":not(."+a.config.cssInfoBlock+")").empty()}}})();var ts=$.tablesorter;$.fn.extend({tablesorter:ts.construct});ts.addParser({id:"text",is:function(a,b,c){return true},format:function(a,b,c,d){var e=b.config;a=$.trim(e.ignoreCase?a.toLocaleLowerCase():a);return e.sortLocaleCompare?ts.replaceAccents(a):a},type:"text"});ts.addParser({id:"currency",is:function(a){return/^\(?[\u00a3$\u20ac\u00a4\u00a5\u00a2?.]\d+/.test(a)},format:function(a,b){return ts.formatFloat(a.replace(/[^\w,. \-()]/g,""),b)},type:"numeric"});ts.addParser({id:"ipAddress",is:function(a){return/^\d{2,3}[\.]\d{2,3}[\.]\d{2,3}[\.]\d{2,3}$/.test(a)},format:function(a,b){var c,d,e=a.split("."),f="",g=e.length;for(c=0;c<g;c++){d=e[c];if(d.length===2){f+="0"+d}else{f+=d}}return ts.formatFloat(f,b)},type:"numeric"});ts.addParser({id:"url",is:function(a){return/^(https?|ftp|file):\/\/$/.test(a)},format:function(a){return $.trim(a.replace(/(https?|ftp|file):\/\//,""))},type:"text"});ts.addParser({id:"isoDate",is:function(a){return/^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}$/.test(a)},format:function(a,b){return ts.formatFloat(a!==""?(new Date(a.replace(/-/g,"/"))).getTime()||"":"",b)},type:"numeric"});ts.addParser({id:"percent",is:function(a){return/\d%\)?$/.test(a)},format:function(a,b){return ts.formatFloat(a.replace(/%/g,""),b)},type:"numeric"});ts.addParser({id:"usLongDate",is:function(a){return a.match(/^[A-Za-z]{3,10}\.? [0-9]{1,2}, ([0-9]{4}|'?[0-9]{2}) (([0-2]?[0-9]:[0-5][0-9])|([0-1]?[0-9]:[0-5][0-9]\s(AM|PM)))$/)},format:function(a,b){return ts.formatFloat((new Date(a)).getTime()||"",b)},type:"numeric"});ts.addParser({id:"shortDate",is:function(a){return/^(\d{2}|\d{4})[\/\-\,\.\s+]\d{2}[\/\-\.\,\s+](\d{2}|\d{4})$/.test(a)},format:function(a,b,c,d){var e=b.config,f=e.headerList[d],g=f.shortDateFormat;if(typeof g==="undefined"){g=f.shortDateFormat=ts.getData(f,e.headers[d],"dateFormat")||e.dateFormat}a=a.replace(/\s+/g," ").replace(/[\-|\.|\,]/g,"/");if(g==="mmddyyyy"){a=a.replace(/(\d{1,2})[\/\s](\d{1,2})[\/\s](\d{4})/,"$3/$1/$2")}else if(g==="ddmmyyyy"){a=a.replace(/(\d{1,2})[\/\s](\d{1,2})[\/\s](\d{4})/,"$3/$2/$1")}else if(g==="yyyymmdd"){a=a.replace(/(\d{4})[\/\s](\d{1,2})[\/\s](\d{1,2})/,"$1/$2/$3")}return ts.formatFloat((new Date(a)).getTime()||"",b)},type:"numeric"});ts.addParser({id:"time",is:function(a){return/^(([0-2]?[0-9]:[0-5][0-9])|([0-1]?[0-9]:[0-5][0-9]\s(am|pm)))$/.test(a)},format:function(a,b){return ts.formatFloat((new Date("2000/01/01 "+a)).getTime()||"",b)},type:"numeric"});ts.addParser({id:"digit",is:function(a){return ts.isDigit(a)},format:function(a,b){return ts.formatFloat(a.replace(/[^\w,. \-()]/g,""),b)},type:"numeric"});ts.addParser({id:"metadata",is:function(a){return false},format:function(a,b,c){var d=b.config,e=!d.parserMetadataName?"sortValue":d.parserMetadataName;return $(c).metadata()[e]},type:"numeric"});ts.addWidget({id:"zebra",format:function(a){var b,c,d,e,f,g,h,i,j=a.config,k=new RegExp(j.cssChildRow,"i"),l=$(a).children("tbody:not(."+j.cssInfoBlock+")"),m=["even","odd"];m=j.widgetZebra&&j.hasOwnProperty("css")?j.widgetZebra.css:j.widgetOptions&&j.widgetOptions.hasOwnProperty("zebra")?j.widgetOptions.zebra:m;if(j.debug){g=new Date}for(h=0;h<l.length;h++){b=$(l[h]);i=b.children("tr").length;if(i>1){e=0;c=b.find("tr:visible");b.addClass("tablesorter-hidden");c.each(function(){d=$(this);if(!k.test(this.className)){e++}f=e%2===0;d.removeClass(m[f?1:0]).addClass(m[f?0:1])});b.removeClass("tablesorter-hidden")}}if(j.debug){ts.benchmark("Applying Zebra widget",g)}}})}(jQuery)
View
202 js/jquery.tablesorter.widgets.js
@@ -1,4 +1,4 @@
-/*! tableSorter 2.3 widgets - updated 5/30/2012
+/*! tableSorter 2.3 widgets - updated 6/1/2012
*
* jQuery UI Theme
* Column Styles
@@ -172,13 +172,15 @@ $.tablesorter.addWidget({
});
// Widget: Filter
-// "filter_startsWith", "filter_childRows", "filter_ignoreCase" & "filter_searchDelay" options in "widgetOptions"
+// "filter_startsWith", "filter_childRows", "filter_ignoreCase",
+// "filter_searchDelay" & "filter_functions" options in "widgetOptions"
// **************************
$.tablesorter.addWidget({
id: "filter",
format: function(table) {
if (!$(table).hasClass('hasFilters')) {
- var i, j, k, l, cv, v, r, t, x, cr, $tb, $tr, $td, reg2,
+ var i, j, k, l, cv, v, val, r, ff, t, x, xi, cr,
+ sel, $tb, $tr, $td, reg2,
c = table.config,
wo = c.widgetOptions,
css = wo.filter_cssFilter || 'tablesorter-filter',
@@ -191,9 +193,8 @@ $.tablesorter.addWidget({
time, timer,
findRows = function(){
if (c.debug) { time = new Date(); }
- v = $t.find('thead').eq(0).children('tr').find('input.' + css).map(function(){
- i = $(this).val() || '';
- return (wo.filter_ignoreCase) ? i.toLocaleLowerCase() : i;
+ v = $t.find('thead').eq(0).children('tr').find('select.' + css + ', input.' + css).map(function(){
+ return $(this).val() || '';
}).get();
cv = v.join('');
for (k = 0; k < b.length; k++ ) {
@@ -202,48 +203,62 @@ $.tablesorter.addWidget({
l = $tr.length;
// loop through the rows
for (j = 0; j < l; j++) {
+ // skip child rows
+ if (reg1.test($tr[j].className)) { continue; }
if (cv === '') {
$tr[j].style.display = '';
} else {
- // skip child rows
- if (!reg1.test($tr[j].className)) {
- r = true;
- cr = $tr.eq(j).nextUntil('tr:not(.' + c.cssChildRow + ')');
- // so, if "table.config.widgetOptions.filter_childRows" is true and there is
- // a match anywhere in the child row, then it will make the row visible
- // checked here so the option can be changed dynamically
- t = (cr.length && (wo && wo.hasOwnProperty('filter_childRows') &&
- typeof wo.filter_childRows !== 'undefined' ? wo.filter_childRows : true)) ? cr.text() : '';
- $td = $tr.eq(j).children('td');
- for (i=0; i < cols; i++) {
- x = $.trim($td.eq(i).text());
- x = wo.filter_ignoreCase ? x.toLocaleLowerCase() : x;
- // ignore if filter is empty
- if (v[i] !== '') {
- // Look for regex
- if (regexp.test(v[i])) {
- reg2 = regexp.exec(v[i]);
- r = RegExp(reg2[1], reg2[2]).test(x);
- // Look for quotes to get an exact match
- } else if (/[\"|\']$/.test(v[i]) && x === v[i].replace(/(\"|\')/g,'')) {
- r = true;
- // Look for wild card: ? = single, or * = multiple
- } else if (/[\?|\*]/.test(v[i])) {
- r = RegExp( v[i].replace(/\?/g, '\\S{1}').replace(/\*/g, '\\S*') ).test(x);
- // Look for match, and add child row data for matching
+ r = true;
+ cr = $tr.eq(j).nextUntil('tr:not(.' + c.cssChildRow + ')');
+ // so, if "table.config.widgetOptions.filter_childRows" is true and there is
+ // a match anywhere in the child row, then it will make the row visible
+ // checked here so the option can be changed dynamically
+ t = (cr.length && (wo && wo.hasOwnProperty('filter_childRows') &&
+ typeof wo.filter_childRows !== 'undefined' ? wo.filter_childRows : true)) ? cr.text() : '';
+ $td = $tr.eq(j).children('td');
+ for (i = 0; i < cols; i++) {
+ x = $.trim($td.eq(i).text());
+ xi = wo.filter_ignoreCase ? x.toLocaleLowerCase() : x;
+ // ignore if filter is empty
+ if (v[i] !== '') {
+ ff = r; // if r is true, show that row
+ // val = case insensitive, v[i] = case sensitive
+ val = wo.filter_ignoreCase ? v[i].toLocaleLowerCase() : v[i];
+ if (wo.filter_functions && wo.filter_functions[i]) {
+ if (wo.filter_functions[i] === true) {
+ // default selector; no "filter-select" class
+ ff = wo.filter_ignoreCase ? val === xi : v[i] === x;
+ } else if (typeof wo.filter_functions[i] === 'function') {
+ // filter callback( exact cell content, parser normalized content, filter input value, column index )
+ ff = wo.filter_functions[i](x, c.cache[k].normalized[j][i], v[i], i);
+ } else if (typeof wo.filter_functions[i][v[i]] === 'function'){
+ // selector option function
+ ff = wo.filter_functions[i][v[i]](x, c.cache[k].normalized[j][i], v[i], i);
+ }
+ // Look for regex
+ } else if (regexp.test(val)) {
+ reg2 = regexp.exec(val);
+ ff = new RegExp(reg2[1], reg2[2]).test(xi);
+ // Look for quotes to get an exact match
+ } else if (/[\"|\']$/.test(val) && xi === val.replace(/(\"|\')/g,'')) {
+ r = (r) ? true : false;
+ // Look for wild card: ? = single, or * = multiple
+ } else if (/[\?|\*]/.test(val)) {
+ ff = new RegExp( val.replace(/\?/g, '\\S{1}').replace(/\*/g, '\\S*') ).test(xi);
+ // Look for match, and add child row data for matching
+ } else {
+ x = (xi + t).indexOf(val);
+ if ( (!wo.filter_startsWith && x >= 0) || (wo.filter_startsWith && x === 0) ) {
+ r = (r) ? true : false;
} else {
- x = (x + t).indexOf(v[i]);
- if ( (!wo.filter_startsWith && x >= 0) || (wo.filter_startsWith && x === 0) ) {
- r = (r) ? true : false;
- } else {
- r = false;
- }
+ r = false;
}
}
+ r = (ff) ? (r ? true : false) : false;
}
- $tr[j].style.display = (r ? '' : 'none');
- if (cr.length) { cr[r ? 'show' : 'hide'](); }
}
+ $tr[j].style.display = (r ? '' : 'none');
+ if (cr.length) { cr[r ? 'show' : 'hide'](); }
}
}
$tb.removeClass('tablesorter-hidden');
@@ -252,38 +267,97 @@ $.tablesorter.addWidget({
$.tablesorter.benchmark("Completed filter widget search", time);
}
$t.trigger('applyWidgets'); // make sure zebra widget is applied
+ },
+ buildSelect = function(i){
+ var o, arry = [];
+ i = parseInt(i, 10);
+ o = '<option value="">' + ($(c.headerList[i]).attr('data-placeholder') || '') + '</option>';
+ for (k = 0; k < b.length; k++ ) {
+ l = c.cache[k].row.length;
+ // loop through the rows
+ for (j = 0; j < l; j++) {
+ // get non-normalized cell content
+ t = c.cache[k].row[j][0].cells[i];
+ arry.push( c.supportsTextContent ? t.textContent : $(t).text() );
+ }
+ }
+ // get unique elements and sort the list
+ arry = arry.getUnique(true);
+ // build option list
+ for (k = 0; k < arry.length; k++) {
+ o += '<option value="' + arry[k] + '">' + arry[k] + '</option>';
+ }
+ $t.find('thead').find('select.' + css + '[data-col="' + i + '"]').append(o);
};
if (c.debug) {
time = new Date();
}
for (i=0; i < cols; i++){
- fr += '<td><input type="search" placeholder="' + ($(c.headerList[i]).attr('data-placeholder') || "") + '" data-col="' + i + '" class="' + css;
+ sel = (wo.filter_functions && wo.filter_functions[i] && typeof wo.filter_functions[i] !== 'function') || $(c.headerList[i]).hasClass('filter-select');
+ fr += '<td>';
+ if (sel){
+ fr += '<select data-col="' + i + '" class="' + css;
+ } else {
+ fr += '<input type="search" placeholder="' + ($(c.headerList[i]).attr('data-placeholder') || "") + '" data-col="' + i + '" class="' + css;
+ }
// use header option - headers: { 1: { filter: false } } OR add class="filter-false"
if ($.tablesorter.getData) {
// get data from jQuery data, metadata, headers option or header class name
fr += $.tablesorter.getData(c.headerList[i], c.headers[i], 'filter') === 'false' ? ' disabled" disabled' : '"';
} else {
// only class names and header options - keep this for compatibility with tablesorter v2.0.5
- fr += ((c.headers[i] && c.headers[i].hasOwnProperty('filter') && c.headers[i].filter === false) || $(c.headerList[i]).is('.filter-false') ) ? ' disabled" disabled' : '"';
+ fr += ((c.headers[i] && c.headers[i].hasOwnProperty('filter') && c.headers[i].filter === false) || $(c.headerList[i]).hasClass('filter-false') ) ? ' disabled" disabled' : '"';
}
- fr += '></td>';
+ fr += (sel ? '></select>' : '>') + '</td>';
}
$t
- .find('thead').eq(0).append(fr += '</tr>')
- .find('input.' + css).bind('keyup search', function(e, delay){
- // ignore arrow and meta keys; allow backspace
- if ((e.which < 32 && e.which !== 8) || (e.which >= 37 && e.which <=40)) { return; }
- // skip delay
- if (delay === false) {
- findRows();
- return;
+ .find('thead').eq(0).append(fr += '</tr>')
+ .find('input.' + css).bind('keyup search', function(e, delay){
+ // ignore arrow and meta keys; allow backspace
+ if ((e.which < 32 && e.which !== 8) || (e.which >= 37 && e.which <=40)) { return; }
+ // skip delay
+ if (delay === false) {
+ findRows();
+ return;
+ }
+ // delay filtering
+ clearTimeout(timer);
+ timer = setTimeout(function(){
+ findRows();
+ }, wo.filter_searchDelay || 300);
+ });
+ if (wo.filter_functions) {
+ // i = column # (string)
+ for (i in wo.filter_functions) {
+ t = $(c.headerList[i]);
+ fr = '';
+ if (typeof i === 'string' && wo.filter_functions[i] === true && !t.hasClass('filter-false')) {
+ buildSelect(i);
+ } else if (typeof i === 'string' && !t.hasClass('filter-false')) {
+ // add custom drop down list
+ for (j in wo.filter_functions[i]) {
+ if (typeof j === 'string') {
+ fr += fr === '' ? '<option>' + (t.attr('data-placeholder') || '') + '</option>' : '';
+ fr += '<option>' + j + '</option>';
+ }
+ }
+ $t.find('thead').find('select.' + css + '[data-col="' + i + '"]').append(fr);
}
- // delay filtering
- clearTimeout(timer);
- timer = setTimeout(function(){
- findRows();
- }, wo.filter_searchDelay || 300);
- });
+ }
+ }
+ // build default select dropdown
+ for (i = 0; i < c.headerList.length; i++) {
+ t = $(c.headerList[i]);
+ // look for the filter-select class, but don't build it twice.
+ if (t.hasClass('filter-select') && !t.hasClass('filter-false') && !(wo.filter_functions && wo.filter_functions[i] === true)){
+ buildSelect(i);
+ }
+ }
+
+ $t.find('select.' + css).bind('change', function(){
+ findRows();
+ });
+
if (c.debug) {
$.tablesorter.benchmark("Applying Filter widget", time);
}
@@ -496,5 +570,15 @@ $.tablesorter.addWidget({
})(jQuery);
-// return an array with unique values
-Array.prototype.getUnique=function(){var b={},c=[],a,d;a=0;for(d=this.length;a<d;++a)if(!(this[a]in b)){c.push(this[a]);b[this[a]]=1}return c.sort()};
+// return an array with unique values https://gist.github.com/461516
+Array.prototype.getUnique = function(s){
+ var c, a = [], o = {}, i, j = 0, l = this.length;
+ for(i=0; i < l; ++i) {
+ c = this[i];
+ if (!o[c]) {
+ o[c] = {};
+ a[j++] = c;
+ }
+ }
+ return (s) ? a.sort() : a;
+};
View
17 js/jquery.tablesorter.widgets.min.js
@@ -1,10 +1,11 @@
-/*! tableSorter 2.3 widgets - updated 5/28/2012 */
+/*! tableSorter 2.3 widgets - updated 6/1/2012 */
;(function(b){
-b.tablesorter.storage=function(a,e,c){var d,g=!1;d={};var j=a.id||b(".tablesorter").index(b(a)),h=window.location.pathname;try{g=!!localStorage.getItem}catch(f){}b.parseJSON&&(g?d=b.parseJSON(localStorage[e])||{}:(d=document.cookie.split(/[;\s|=]/),a=b.inArray(e,d)+1,d=0!==a?b.parseJSON(d[a])||{}:{}));if(c&&JSON&&JSON.hasOwnProperty("stringify")){if(!d[h]||!d[h][j])d[h]||(d[h]={});d[h][j]=c;g?localStorage[e]=JSON.stringify(d):(a=new Date,a.setTime(a.getTime()+31536E6),document.cookie= e+"="+JSON.stringify(d).replace(/\"/g,'"')+"; expires="+a.toGMTString()+"; path=/")}else return d&&d.hasOwnProperty(h)&&d[h].hasOwnProperty(j)?d[h][j]:{}};
-b.tablesorter.addWidget({id:"uitheme",format:function(a){var e,c,d,g,j,h=b(a),f=a.config,k=f.widgetOptions,i=["ui-icon-arrowthick-2-n-s","ui-icon-arrowthick-1-s","ui-icon-arrowthick-1-n"],i=f.widgetUitheme&&f.widgetUitheme.hasOwnProperty("css")?f.widgetUitheme.css||i:k&&k.hasOwnProperty("uitheme")?k.uitheme:i;d=i.join(" ");f.debug&&(e=new Date); h.hasClass("ui-theme")||(h.addClass("ui-widget ui-widget-content ui-corner-all ui-theme"),b.each(f.headerList,function(){b(this).addClass("ui-widget-header ui-corner-all ui-state-default").append('<span class="ui-icon"/>').wrapInner('<div class="tablesorter-inner"/>').hover(function(){b(this).addClass("ui-state-hover")},function(){b(this).removeClass("ui-state-hover")})}));b.each(f.headerList,function(a){g=b(this);if(this.sortDisabled)g.find("span.ui-icon").removeClass(d+" ui-icon");else{c=g.hasClass(f.cssAsc)? i[1]:g.hasClass(f.cssDesc)?i[2]:g.hasClass(f.cssHeader)?i[0]:"";j=h.hasClass("hasStickyHeaders")?h.find("tr."+(k.stickyHeaders||"tablesorter-stickyHeader")).find("th").eq(a).add(g):g;j[c===i[0]?"removeClass":"addClass"]("ui-state-active").find("span.ui-icon").removeClass(d).addClass(c)}});f.debug&&b.tablesorter.benchmark("Applying uitheme widget",e)}});
-b.tablesorter.addWidget({id:"columns",format:function(a){var e,c,d,g,j,h,f,k,i=a.config,o=b(a).children("tbody:not(."+i.cssInfoBlock+")"),m=i.sortList, p=m.length,n=["primary","secondary","tertiary"],n=i.widgetColumns&&i.widgetColumns.hasOwnProperty("css")?i.widgetColumns.css||n:i.widgetOptions&&i.widgetOptions.hasOwnProperty("columns")?i.widgetOptions.columns||n:n;j=n.length-1;h=n.join(" ");i.debug&&(g=new Date);for(k=0;k<o.length;k++)a=b(o[k]),e=a.addClass("tablesorter-hidden").children("tr"),e.each(function(){d=b(this);if("none"!==this.style.display&&(c=d.children().removeClass(h),m&&m[0]&&(c.eq(m[0][0]).addClass(n[0]),1<p)))for(f=1;f<p;f++)c.eq(m[f][0]).addClass(n[f]|| n[j])}),a.removeClass("tablesorter-hidden");i.debug&&b.tablesorter.benchmark("Applying Columns widget",g)}});
-b.tablesorter.addWidget({id:"filter",format:function(a){if(!b(a).hasClass("hasFilters")){var e,c,d,g,j,h,f,k,i,o,m,p,n,l=a.config,q=l.widgetOptions,r=q.filter_cssFilter||"tablesorter-filter",s=b(a).addClass("hasFilters"),u=s.children("tbody:not(."+l.cssInfoBlock+")"),v=l.parsers.length,a='<tr class="'+r+'">',y=RegExp(l.cssChildRow),t,w,x=function(){l.debug&&(t=new Date);h=s.find("thead").eq(0).children("tr").find("input."+ r).map(function(){e=b(this).val()||"";return q.filter_ignoreCase?e.toLocaleLowerCase():e}).get();j=h.join("");for(d=0;d<u.length;d++){m=b(u[d]);p=m.addClass("tablesorter-hidden").children("tr");g=p.length;for(c=0;c<g;c++)if(""===j)p[c].style.display="";else if(!y.test(p[c].className)){f=!0;o=p.eq(c).nextUntil("tr:not(."+l.cssChildRow+")");k=o.length&&(q&&q.hasOwnProperty("filter_childRows")&&"undefined"!==typeof q.filter_childRows?q.filter_childRows:1)?o.text():"";n=p.eq(c).children("td");for(e=0;e< v;e++)""!==h[e]&&(i=b.trim(n.eq(e).text()+k),i=(q.filter_ignoreCase?i.toLocaleLowerCase():i).indexOf(h[e]),f=!q.filter_startsWith&&0<=i||q.filter_startsWith&&0===i?f?!0:!1:!1);p[c].style.display=f?"":"none";if(o.length)o[f?"show":"hide"]()}m.removeClass("tablesorter-hidden")}l.debug&&b.tablesorter.benchmark("Completed filter widget search",t);s.trigger("applyWidgets")};l.debug&&(t=new Date);for(e=0;e<v;e++)a+='<td><input type="search" data-col="'+e+'" class="'+r,a=b.tablesorter.getData?a+("false"=== b.tablesorter.getData(l.headerList[e],l.headers[e],"filter")?' disabled" disabled':'"'):a+(l.headers[e]&&l.headers[e].hasOwnProperty("filter")&&!1===l.headers[e].filter||b(l.headerList[e]).is(".filter-false")?' disabled" disabled':'"'),a+="></td>";s.find("thead").eq(0).append(a+="</tr>").find("input."+r).bind("keyup search",function(b,a){32>b.which&&8!==b.which||37<=b.which&&40>=b.which||(!1===a?x():(clearTimeout(w),w=setTimeout(function(){x()},q.filter_searchDelay||300)))});l.debug&&b.tablesorter.benchmark("Applying Filter widget", t)}}});
-b.tablesorter.addWidget({id:"stickyHeaders",format:function(a){if(!b(a).hasClass("hasStickyHeaders")){var e=b(a).addClass("hasStickyHeaders"),c=a.config.widgetOptions,d=b(window),g=b(a).children("thead"),j=g.children("tr:not(.sticky-false)").children(),h=c.stickyHeaders||"tablesorter-stickyHeader",f=j.eq(0),k=e.find("tfoot"),i=g.find("tr.tablesorter-header:not(.sticky-false)").clone().removeClass("tablesorter-header").addClass(h).css({width:g.outerWidth(!0),position:"fixed",left:f.offset().left, margin:0,top:0,visibility:"hidden",zIndex:10}),o=i.children(),m="";e.bind("sortEnd",function(a,c){var d=b(c).find("thead tr"),e=d.filter("."+h).children();d.filter(":not(."+h+")").children().each(function(a){e.eq(a).attr("class",b(this).attr("class"))})}).bind("pagerComplete",function(){d.resize()});j.each(function(a){var c=b(this);o.eq(a).bind("mouseup",function(b){c.trigger(b,!0)}).bind("mousedown",function(){this.onselectstart=function(){return!1};return!1}).find(".tablesorter-header-inner").width(c.find(".tablesorter-header-inner").width())}); g.prepend(i);d.scroll(function(){var b=f.offset(),a=d.scrollTop(),c=e.height()-(f.height()+(k.height()||0)),a=a>b.top&&a<b.top+c?"visible":"hidden";i.css({left:b.left-d.scrollLeft(),visibility:a});a!==m&&(d.resize(),m=a)}).resize(function(){var a=0;i.css({left:f.offset().left-d.scrollLeft(),width:g.outerWidth()}).each(function(c){b(this).css("top",a);a+=g.find("tr").eq(c).outerHeight()});o.find(".tablesorter-header-inner").each(function(a){b(this).width(j.eq(a).find(".tablesorter-header-inner").width())})})}}});
-b.tablesorter.addWidget({id:"resizable",format:function(a){if(!b(a).hasClass("hasResizable")){b(a).addClass("hasResizable");var e,c,d=a.config,g=b(d.headerList).filter(":gt(0)"),j=0,h=null,f=null,k=function(){j=0;h=f=null;b(window).trigger("resize")};if(c=b.tablesorter.storage?b.tablesorter.storage(a,"tablesorter-resizable"):"")for(e in c)!isNaN(e)&&e<d.headerList.length&&b(d.headerList[e]).width(c[e]);g.each(function(){b(this).append('<div class="tablesorter-resizer" style="cursor:w-resize;position:absolute;height:100%;width:20px;left:-20px;top:0;z-index:1;"></div>').wrapInner('<div style="position:relative;height:100%;width:100%"></div>')}).bind("mousemove", function(b){if(0!==j&&h){var a=b.pageX-j;h.width()<-a||f&&f.width()<=a||(f.width(f.width()+a),j=b.pageX)}}).bind("mouseup",function(){c&&(b.tablesorter.storage&&h)&&(c[f.index()]=f.width(),b.tablesorter.storage(a,"tablesorter-resizable",c));k();return!1}).find(".tablesorter-resizer").bind("mousedown",function(a){h=b(a.target).closest("th");f=h.prev();j=a.pageX;return!1});b(a).find("thead").bind("mouseup mouseleave",function(){k()})}}});
-b.tablesorter.addWidget({id:"saveSort",init:function(a,b,c){c.format(a, !0)},format:function(a,e){var c,d,g=a.config;c={sortList:g.sortList};g.debug&&(d=new Date);b(a).hasClass("hasSaveSort")?a.hasInitialized&&b.tablesorter.storage&&(b.tablesorter.storage(a,"tablesorter-savesort",c),g.debug&&b.tablesorter.benchmark("saveSort widget: Saving last sort: "+g.sortList,d)):(b(a).addClass("hasSaveSort"),c="",b.tablesorter.storage&&(c=(c=b.tablesorter.storage(a,"tablesorter-savesort"))&&c.hasOwnProperty("sortList")&&b.isArray(c.sortList)?c.sortList:"",g.debug&&b.tablesorter.benchmark("saveSort: Last sort loaded: "+ c,d)),e&&c&&0<c.length?g.sortList=c:a.hasInitialized&&(c&&0<c.length)&&b(a).trigger("sorton",[c]))}})
+b.tablesorter.storage=function(c,a,e){var d,h=!1;d={};var l=c.id||b(".tablesorter").index(b(c)),g=window.location.pathname;try{h=!!localStorage.getItem}catch(f){}b.parseJSON&&(h?d=b.parseJSON(localStorage[a])||{}:(d=document.cookie.split(/[;\s|=]/),c=b.inArray(a,d)+1,d=0!==c?b.parseJSON(d[c])||{}:{}));if(e&&JSON&&JSON.hasOwnProperty("stringify")){if(!d[g]||!d[g][l])d[g]||(d[g]={});d[g][l]=e;h?localStorage[a]=JSON.stringify(d):(c=new Date,c.setTime(c.getTime()+31536E6),document.cookie= a+"="+JSON.stringify(d).replace(/\"/g,'"')+"; expires="+c.toGMTString()+"; path=/")}else return d&&d.hasOwnProperty(g)&&d[g].hasOwnProperty(l)?d[g][l]:{}};
+b.tablesorter.AddWidget({id:"uitheme",format:function(c){var a,e,d,h,l,g=b(c),f=c.config,m=f.widgetOptions,i=["ui-icon-arrowthick-2-n-s","ui-icon-arrowthick-1-s","ui-icon-arrowthick-1-n"],i=f.widgetUitheme&&f.widgetUitheme.hasOwnProperty("css")?f.widgetUitheme.css||i:m&&m.hasOwnProperty("uitheme")?m.uitheme:i;d=i.join(" ");f.debug&&(a=new Date); g.hasClass("ui-theme")||(g.addClass("ui-widget ui-widget-content ui-corner-all ui-theme"),b.each(f.headerList,function(){b(this).addClass("ui-widget-header ui-corner-all ui-state-default").append('<span class="ui-icon"/>').wrapInner('<div class="tablesorter-inner"/>').hover(function(){b(this).addClass("ui-state-hover")},function(){b(this).removeClass("ui-state-hover")})}));b.each(f.headerList,function(a){h=b(this);if(this.sortDisabled)h.find("span.ui-icon").removeClass(d+" ui-icon");else{e=h.hasClass(f.cssAsc)? i[1]:h.hasClass(f.cssDesc)?i[2]:h.hasClass(f.cssHeader)?i[0]:"";l=g.hasClass("hasStickyHeaders")?g.find("tr."+(m.stickyHeaders||"tablesorter-stickyHeader")).find("th").eq(a).add(h):h;l[e===i[0]?"removeClass":"addClass"]("ui-state-active").find("span.ui-icon").removeClass(d).addClass(e)}});f.debug&&b.tablesorter.benchmark("Applying uitheme widget",a)}});
+b.tablesorter.AddWidget({id:"columns",format:function(c){var a,e,d,h,l,g,f,m,i=c.config,o=b(c).children("tbody:not(."+i.cssInfoBlock+")"),p=i.sortList, r=p.length,q=["primary","secondary","tertiary"],q=i.widgetColumns&&i.widgetColumns.hasOwnProperty("css")?i.widgetColumns.css||q:i.widgetOptions&&i.widgetOptions.hasOwnProperty("columns")?i.widgetOptions.columns||q:q;l=q.length-1;g=q.join(" ");i.debug&&(h=new Date);for(m=0;m<o.length;m++)c=b(o[m]),a=c.addClass("tablesorter-hidden").children("tr"),a.each(function(){d=b(this);if("none"!==this.style.display&&(e=d.children().removeClass(g),p&&p[0]&&(e.eq(p[0][0]).addClass(q[0]),1<r)))for(f=1;f<r;f++)e.eq(p[f][0]).addClass(q[f]|| q[l])}),c.removeClass("tablesorter-hidden");i.debug&&b.tablesorter.benchmark("Applying Columns widget",h)}});
+b.tablesorter.AddWidget({id:"filter",format:function(c){if(!b(c).hasClass("hasFilters")){var a,e,d,h,l,g,f,m,i,o,p,r,q,w,t,A,x,k=c.config,j=k.widgetOptions,s=j.filter_cssFilter||"tablesorter-filter",u=b(c).addClass("hasFilters"),y=u.children("tbody:not(."+k.cssInfoBlock+")"),B=k.parsers.length,n='<tr class="'+s+'">',C=/^\/((?:\\\/|[^\/])+)\/([mig]{0,3})?$/,F=RegExp(k.cssChildRow),v,D,z=function(){k.debug&& (v=new Date);g=u.find("thead").eq(0).children("tr").find("select."+s+", input."+s).map(function(){return b(this).val()||""}).get();l=g.join("");for(d=0;d<y.length;d++){w=b(y[d]);t=w.addClass("tablesorter-hidden").children("tr");h=t.length;for(e=0;e<h;e++)if(!F.test(t[e].className))if(""===l)t[e].style.display="";else{m=!0;q=t.eq(e).nextUntil("tr:not(."+k.cssChildRow+")");o=q.length&&(j&&j.hasOwnProperty("filter_childRows")&&"undefined"!==typeof j.filter_childRows?j.filter_childRows:1)?q.text():""; A=t.eq(e).children("td");for(a=0;a<B;a++)p=b.trim(A.eq(a).text()),r=j.filter_ignoreCase?p.toLocaleLowerCase():p,""!==g[a]&&(i=m,f=j.filter_ignoreCase?g[a].toLocaleLowerCase():g[a],j.filter_functions&&j.filter_functions[a]?!0===j.filter_functions[a]?i=j.filter_ignoreCase?f===r:g[a]===p:"function"===typeof j.filter_functions[a]?i=j.filter_functions[a](p,k.cache[d].normalized[e][a],g[a],a):"function"===typeof j.filter_functions[a][g[a]]&&(i=j.filter_functions[a][g[a]](p,k.cache[d].normalized[e][a],g[a], a)):C.test(f)?(x=C.exec(f),i=RegExp(x[1],x[2]).test(r)):/[\"|\']$/.test(f)&&r===f.replace(/(\"|\')/g,"")?m=m?!0:!1:/[\?|\*]/.test(f)?i=RegExp(f.replace(/\?/g,"\\S{1}").replace(/\*/g,"\\S*")).test(r):(p=(r+o).indexOf(f),m=!j.filter_startsWith&&0<=p||j.filter_startsWith&&0===p?m?!0:!1:!1),m=i?m?!0:!1:!1);t[e].style.display=m?"":"none";if(q.length)q[m?"show":"hide"]()}w.removeClass("tablesorter-hidden")}k.debug&&b.tablesorter.benchmark("Completed filter widget search",v);u.trigger("applyWidgets")},E= function(a){var c,f=[],a=parseInt(a,10);c='<option value="">'+(b(k.headerList[a]).attr("data-placeholder")||"")+"</option>";for(d=0;d<y.length;d++){h=k.cache[d].row.length;for(e=0;e<h;e++)o=k.cache[d].row[e][0].cells[a],f.push(k.supportsTextContent?o.textContent:b(o).text())}f=f.getUnique(!0);for(d=0;d<f.length;d++)c+='<option value="'+f[d]+'">'+f[d]+"</option>";u.find("thead").find("select."+s+'[data-col="'+a+'"]').append(c)};k.debug&&(v=new Date);for(a=0;a<B;a++)c=j.filter_functions&&j.filter_functions[a]&& "function"!==typeof j.filter_functions[a]||b(k.headerList[a]).hasClass("filter-select"),n+="<td>",n=c?n+('<select data-col="'+a+'" class="'+s):n+('<input type="search" placeholder="'+(b(k.headerList[a]).attr("data-placeholder")||"")+'" data-col="'+a+'" class="'+s),n=b.tablesorter.getData?n+("false"===b.tablesorter.getData(k.headerList[a],k.headers[a],"filter")?' disabled" disabled':'"'):n+(k.headers[a]&&k.headers[a].hasOwnProperty("filter")&&!1===k.headers[a].filter||b(k.headerList[a]).hasClass("filter-false")? ' disabled" disabled':'"'),n+=(c?"></select>":">")+"</td>";u.find("thead").eq(0).append(n+="</tr>").find("input."+s).bind("keyup search",function(a,b){32>a.which&&8!==a.which||37<=a.which&&40>=a.which||(!1===b?z():(clearTimeout(D),D=setTimeout(function(){z()},j.filter_searchDelay||300)))});if(j.filter_functions)for(a in j.filter_functions)if(o=b(k.headerList[a]),n="","string"===typeof a&&!0===j.filter_functions[a]&&!o.hasClass("filter-false"))E(a);else if("string"===typeof a&&!o.hasClass("filter-false")){for(e in j.filter_functions[a])"string"=== typeof e&&(n+=""===n?"<option>"+(o.attr("data-placeholder")||"")+"</option>":"",n+="<option>"+e+"</option>");u.find("thead").find("select."+s+'[data-col="'+a+'"]').append(n)}for(a=0;a<k.headerList.length;a++)o=b(k.headerList[a]),o.hasClass("filter-select")&&(!o.hasClass("filter-false")&&!(j.filter_functions&&!0===j.filter_functions[a]))&&E(a);u.find("select."+s).bind("change",function(){z()});k.debug&&b.tablesorter.benchmark("Applying Filter widget",v)}}});
+b.tablesorter.AddWidget({id:"stickyHeaders", format:function(c){if(!b(c).hasClass("hasStickyHeaders")){var a=b(c).addClass("hasStickyHeaders"),e=c.config.widgetOptions,d=b(window),h=b(c).children("thead"),l=h.children("tr:not(.sticky-false)").children(),g=e.stickyHeaders||"tablesorter-stickyHeader",f=l.eq(0),m=a.find("tfoot"),i=h.find("tr.tablesorter-header:not(.sticky-false)").clone().removeClass("tablesorter-header").addClass(g).css({width:h.outerWidth(!0),position:"fixed",left:f.offset().left,margin:0,top:0,visibility:"hidden",zIndex:10}), o=i.children(),p="";a.bind("sortEnd",function(a,d){var c=b(d).find("thead tr"),e=c.filter("."+g).children();c.filter(":not(."+g+")").children().each(function(a){e.eq(a).attr("class",b(this).attr("class"))})}).bind("pagerComplete",function(){d.resize()});l.each(function(a){var d=b(this);o.eq(a).bind("mouseup",function(a){d.trigger(a,!0)}).bind("mousedown",function(){this.onselectstart=function(){return!1};return!1}).find(".tablesorter-header-inner").width(d.find(".tablesorter-header-inner").width())}); h.prepend(i);d.scroll(function(){var b=f.offset(),c=d.scrollTop(),e=a.height()-(f.height()+(m.height()||0)),c=c>b.top&&c<b.top+e?"visible":"hidden";i.css({left:b.left-d.scrollLeft(),visibility:c});c!==p&&(d.resize(),p=c)}).resize(function(){var a=0;i.css({left:f.offset().left-d.scrollLeft(),width:h.outerWidth()}).each(function(c){b(this).css("top",a);a+=h.find("tr").eq(c).outerHeight()});o.find(".tablesorter-header-inner").each(function(a){b(this).width(l.eq(a).find(".tablesorter-header-inner").width())})})}}});
+b.tablesorter.AddWidget({id:"resizable",format:function(c){if(!b(c).hasClass("hasResizable")){b(c).addClass("hasResizable");var a,e,d=c.config,h=b(d.headerList).filter(":gt(0)"),l=0,g=null,f=null,m=function(){l=0;g=f=null;b(window).trigger("resize")};if(e=b.tablesorter.storage?b.tablesorter.storage(c,"tablesorter-resizable"):"")for(a in e)!isNaN(a)&&a<d.headerList.length&&b(d.headerList[a]).width(e[a]);h.each(function(){b(this).append('<div class="tablesorter-resizer" style="cursor:w-resize;position:absolute;height:100%;width:20px;left:-20px;top:0;z-index:1;"></div>').wrapInner('<div style="position:relative;height:100%;width:100%"></div>')}).bind("mousemove", function(a){if(0!==l&&g){var b=a.pageX-l;g.width()<-b||f&&f.width()<=b||(f.width(f.width()+b),l=a.pageX)}}).bind("mouseup",function(){e&&(b.tablesorter.storage&&g)&&(e[f.index()]=f.width(),b.tablesorter.storage(c,"tablesorter-resizable",e));m();return!1}).find(".tablesorter-resizer").bind("mousedown",function(a){g=b(a.target).closest("th");f=g.prev();l=a.pageX;return!1});b(c).find("thead").bind("mouseup mouseleave",function(){m()})}}});
+b.tablesorter.AddWidget({id:"saveSort",init:function(b,a,e){e.format(b, !0)},format:function(c,a){var e,d,h=c.config;e={sortList:h.sortList};h.debug&&(d=new Date);b(c).hasClass("hasSaveSort")?c.hasInitialized&&b.tablesorter.storage&&(b.tablesorter.storage(c,"tablesorter-savesort",e),h.debug&&b.tablesorter.benchmark("saveSort widget: Saving last sort: "+h.sortList,d)):(b(c).addClass("hasSaveSort"),e="",b.tablesorter.storage&&(e=(e=b.tablesorter.storage(c,"tablesorter-savesort"))&&e.hasOwnProperty("sortList")&&b.isArray(e.sortList)?e.sortList:"",h.debug&&b.tablesorter.benchmark("saveSort: Last sort loaded: "+ e,d)),a&&e&&0<e.length?h.sortList=e:c.hasInitialized&&(e&&0<e.length)&&b(c).trigger("sorton",[e]))}})
})(jQuery);
+Array.prototype.getUnique=function(b){var c,a=[],e={},d,h=0,l=this.length;for(d=0;d<l;++d)c=this[d],e[c]||(e[c]={},a[h++]=c);return b?a.sort():a};
View
2 package.json
@@ -1,6 +1,6 @@
{
"name": "tablesorter",
- "version": "2.3.5",
+ "version": "2.3.6",
"title": "tablesorter",
"author": {
"name": "Christian Bach",

0 comments on commit 1093a3d

Please sign in to comment.
Something went wrong with that request. Please try again.