filter widget functions

This commit is contained in:
Rob Garrison 2012-06-01 09:49:46 -05:00
parent 10fe23f1f4
commit 1093a3da14
14 changed files with 659 additions and 92 deletions

Binary file not shown.

Binary file not shown.

View File

@ -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);
}

Binary file not shown.

View File

@ -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 File

@ -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 File

@ -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 File

@ -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 @@ $(function(){
<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 @@ $(function(){
<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 @@ $(function(){
<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 @@ $(function(){
<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 @@ $(function(){
<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 @@ $(function(){
<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 @@ table.tablesorter thead tr.filters input.disabled {
<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 File

@ -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 @@ $(function(){
<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 File

@ -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 = {

File diff suppressed because one or more lines are too long

View File

@ -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,11 +203,11 @@ $.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
@ -215,58 +216,99 @@ $.tablesorter.addWidget({
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++) {
for (i = 0; i < cols; i++) {
x = $.trim($td.eq(i).text());
x = wo.filter_ignoreCase ? x.toLocaleLowerCase() : x;
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
if (regexp.test(v[i])) {
reg2 = regexp.exec(v[i]);
r = RegExp(reg2[1], reg2[2]).test(x);
} 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(v[i]) && x === v[i].replace(/(\"|\')/g,'')) {
r = true;
} else if (/[\"|\']$/.test(val) && xi === val.replace(/(\"|\')/g,'')) {
r = (r) ? true : false;
// 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);
} 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 = (x + t).indexOf(v[i]);
x = (xi + t).indexOf(val);
if ( (!wo.filter_startsWith && x >= 0) || (wo.filter_startsWith && x === 0) ) {
r = (r) ? true : false;
} else {
r = false;
}
}
r = (ff) ? (r ? true : false) : false;
}
}
$tr[j].style.display = (r ? '' : 'none');
if (cr.length) { cr[r ? 'show' : 'hide'](); }
}
}
}
$tb.removeClass('tablesorter-hidden');
}
if (c.debug) {
$.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>')
@ -284,6 +326,38 @@ $.tablesorter.addWidget({
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);
}
}
}
// 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 File

@ -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 File

@ -1,6 +1,6 @@
{
"name": "tablesorter",
"version": "2.3.5",
"version": "2.3.6",
"title": "tablesorter",
"author": {
"name": "Christian Bach",