From 1093a3da14fca723b9604f575d19f67eeec8bc66 Mon Sep 17 00:00:00 2001 From: Rob Garrison Date: Fri, 1 Jun 2012 09:49:46 -0500 Subject: [PATCH] filter widget functions --- README.markdown | Bin 23192 -> 26362 bytes css/blue/blue.zip | Bin 1985 -> 2000 bytes css/blue/style.css | 6 +- css/green/green.zip | Bin 14523 -> 14533 bytes css/green/style.css | 6 +- css/ui/style.css | 6 +- docs/example-widget-filter-custom.html | 335 +++++++++++++++++++++++++ docs/example-widget-filter.html | 45 ++-- docs/index.html | 124 +++++++++ js/jquery.tablesorter.js | 4 +- js/jquery.tablesorter.min.js | 4 +- js/jquery.tablesorter.widgets.js | 202 ++++++++++----- js/jquery.tablesorter.widgets.min.js | 17 +- package.json | 2 +- 14 files changed, 659 insertions(+), 92 deletions(-) create mode 100644 docs/example-widget-filter-custom.html diff --git a/README.markdown b/README.markdown index 064058b12da5b87f9acdad00fa6f06c3b6cc1f62..da7f5ad10bf228de8a97034426560d849156eec5 100644 GIT binary patch delta 2393 zcma)7&2AHC6ulr-4J2tB%rq^5W;zm5h_Hi^>dFZP5k%BPC5U#>MM~?5J^2y#IM`#6 zY&zlz5c)RV_5~1C)phrk5HHYGAE8TDoO7?o;|U<4$g#g~?$5dBo_puFzfQb*apHMv zX0j%}EJ#h3r0O2deE#7b38f{Gd$2ZtA(B}3aE_%Zk#z8hC6PWn66v~^!NrwjnU>Qy z`?847x>~knzz8@WNE_bt-IFeU^R|ck1mA})t$FU>VCwEZybj=#;K?@Z4)K&Zw&e)_ ziKZpA*~O`W-ytkRDZe9n!-Z?!jAqb?KnlOa-79fx3jr>MsYQfsA4q_iYKPg-8EQ(SI@gw zm8tZ$x;8aUN6Ty?XhuPV(wXq462eX!hh;9^?{GKPBl(67w~QllM=!Lu<^k!xsL zPp%uAtGG6KaTNM6V^>KZopVwzYue(#Q~~{>G~DA_3FGz&SZ>2A14@{7bD*u@urh9l z0m;TN!ub(Sd_s1sas?3s&1L%GU0v_q6aYJAqoYW_9rmA48?pg#u`>He8&QN7;5o}I zrrJP2+_}f|9{RF4?29F#nn=)_-RK}v8-?ua-r#_|Unlw)xp zT@jLX!J03(ktmlrm1&TV73`jtXVVy^ak)@Fj7w1vvMoP)FnOl%K=;AsFpo)={iJU$ zF0RYb`q3V?#B`GNj+h3}QIsmvIk0S?SdOnSnkdV*J4dFl*${-ljb*Yn{$}_d&nT!v zc;&N2v2cH~OwNG&Z}ChzK#;6rhBP;tuAx%ywBm~8d7R-Txe9%5$k=-M>*zIl5U3DWOO`xW;?Hb%1Y*iep$@V2`oc3w!?I^&Grey~SujBrn^H%x*mf+8N zN?~O0Fv2i0YzG~wE|1_j&^VzBzn*oiFVCI|Q668YNAAgaZ<4!fNUXd2)m%Lr$T6&% zCDTg>5ve57NG!zN2FA1^RO2)Ajjd@92+a%i|Wvu!mS3X}do@D7jz1 LJNM`IOl|!&N7BUz delta 14 Wcmex$mT|^b#tkWgn~%wwcme=669!KJ diff --git a/css/blue/blue.zip b/css/blue/blue.zip index 90f259fa7046f88fea4a8911f84cabee80e4e3b8..7b24d0e666b609a8fcc87064e001df392b78309f 100644 GIT binary patch delta 1093 zcmV-L1iJgd56};PP)h>@6aWGM2mpx!zChcYtE;gC006EH000R90047zd2D4aV{>!8 zS5b4*I1qk5X7~@9xw#pxZDO}HB_z`ax0Jgu6k0e6^i8(bwpzu~$ue%Z;lJNXj@u;I zaatJSX&Onp+HbYruGZcbIT8hse^QtN+43GgGBgy>ci*{x)CM&9@A0GGVwssO7gPf%GvY@8*j8R%ZFXvDK*M0}k5)&O>=$pMo#Pc!FQgA;H7__?!t z>lZ=9B$tAJv&w$6wQAc6F>WcS%F)~U*XkkcRfnJ`W6rgGH*Ru{^i!a$#mU7%uaa{( zye$$6bdfMwpa2F>%hE-9(Q`hf34$rKc*3ZmBRBRE9*;ws!@>T}J74_u_Jv4ao(Hdj zNe~3br{?s`^Ss&LgQMUCCr*Obf%{wp!8QJye7c%{YzMP4qo1?%!>Rn&JWVb?olP&2 z=lio)7w19nwmdxib6jC8Q*NLEqlNz?FfByyXTZFL<7{?-b0^*llRiSLRTm^RD4=FU zGCBXbl1xhG+;EBfk07(b)jUbfDoek=GG!Dx#=ZrxWYsPaW=*-r?4C;#%O1YdbiBx0Y#H5`jIFuTV;`TmwLa-Sd_j0?^lN1Y^;n8xn%!ZIspVBAKyHz_(&;rq}^H*a&jxP8)zW_G;?H zTuZeY8o*#9$Xy%7!+5yFpO{->ld|GZGgWw|3bT|$l~!Yg%|SraB<�JM8BJ*I=h$ z+ldhxNI`SgSM*8A0%Z4O)e)22%!Dm4TOPSj9QyS(_Y26ansY(gHyVSr(C-i2n}L(T zcPyb&`eeR(IPmSQ^X-37O9KRxPX-#Z=L0ta4T%E2K--+FtFZ$B0IriO21p6m0{{SG zY+++-lPw1rlQ#qq3jhEB0096X0000uldlFj0il!W20H=*1(PNRIRRgjU@6aWGM2mlF8yFg>8%Fm($002o1000R90047zd2D4aV{>!8 zS8Z?8FcAI>692&xLV|5+vaycRY9F#Opoqc7%Yc1zVkhzD#>R1$g=zntv(s#CNt$jT z8ui8Yo$oo{bLXqOhW2<)(U*iyC|YwLJ=8ehv}Zpvp)^&0=<3nK2a!m%6X6Ntv0oHcHmj+E5uF%8 z?}-^|dZ``ESq#dYM%r2uicsZb5{E2}hscA;>jtnJO%CX!d74<)8l0dz6kfM>Z~Q`l z7-fPpQrT~RwpMLhA%-nEmKk_k|5`kRt?CdYCd9h7ZO2W{poFP;8b!Jhr5OX z4lW`hau9&vDN)!+&w9=#I0i7e;!g?IcxcCN%%V|%GrF_A@yX+FKEC3~>tp|&KlXip z|4<(uxvpEj?eF;qFmd3&_wDP%_s`*L{QYda?w3V>ihrcZ*F*7BKaWqpA5Bi;m)qsL zlVjiiSnTdT8&w#KglXD<(ZK&3m=J>H8 z&xf}~%>}X5s)ccm5zd!b0%yW7H(ESO0&`s!NnC?MffIh?E?!dkhMS8c;8jU*y zm(c$l-SJ?r#9Ku={s5&xp89`8cM;M52yY{QsC$IhV4sgKDC8L>kjW@v1h_jb7T_zC zWkrLWaZ?j!RSjQd(c6VEU8>3Zrj~#8e{(nKQ*4 zbW^O2P0Nd{#g66CIpqCqs6<4?p4u~AX+r@lU@cIv-Sfw0u2dFyFg>8%Fm($002poItEAy$pZiYVr*e!Ym+<&7?VZ>5DNeR w00031AOHXWDU-eiIRTQB_y#)y^8}MM2RQ*ylWzw(0kxB<2O$O$1^@s60N0iMd;kCd diff --git a/css/blue/style.css b/css/blue/style.css index ff5d281c..acb1b4ba 100644 --- a/css/blue/style.css +++ b/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); } \ No newline at end of file diff --git a/css/green/green.zip b/css/green/green.zip index f902ac4d9e7804e13308576b629a128ca66921e8..35385087667d5471a48e77a9b2a9906bd66fb629 100644 GIT binary patch delta 835 zcmV-J1HAmZam8_eP)h>@6aWGM2mq-9zChdo2KL$l005v0000R90047zd2D4aV{>z* zR#9);AP|0DrTzz`sZtx&j@v0!n`%$nKbWRTd&B0iQ3)WxOVX+TeFwy;yV`N0%93s1 zxck04_+UOGwFOYbH?RUSo1dR~T1v>{+iB~;lE3F?pSV_kKI3#H0#qD zDn*UcC2${OY0JQ7&d^GzdPxfGd>MdyJw(Ab!`&>BORo3e$qfQ_S_+mz3_I-24CEy> z4heOCBRma%Wh|mksdza6s!Qk>7M`OgH$WNjBU#{DdmK#A_qAJ+*2>HBsb;xR^%bc= z1?%0%f&uEY0}=BOb2Rb&W|l19#rKvfEUd+dy;56IH-5M(ueo?giESVm)7IwH!$UnI)ac?gunb1f&S#``fZIirMlc|h_)@biStBgKg%9!~g5U9Cv?w-*KSA}!=X2hJ`c2DrrCzaCsU5sc;6zEW0#AbN z^+6h))fk+r;JiA5&Xgax=N#@2$U4g%R9dlV#CyB3SnQ5-c6S8kNl!iyPev<7^U<1@jtVY3KP^(w;R5GT4vTydZ%NSxPi|=%dbt}1 z{kkZw0*imM_X4am4XFaYK->Wa_Symf0HBkwH%I~j1C#nUGXXP`E;uy-4U=RzH36}c Nnm8K@6aWGM2mt*{yFfQ=WOUF10027*000R90047zd2D4aV{>z* zmTha>Fc8OIuh8#sFbZp^9k(N;P1&pM8;mj7JJ~wfqKYJBc}ZIO-FLF`;4XHYPz+8a zo$h{jlK%2^0;NOL;454pOs1C?p5+SD_FWt2(ZTEG#V28Zv`++ENVT2=bCRhi>djg4 zTsqTeo)ktIH;2y!4^J3eFjq=Fhuh4qAhRBBXLj|p^;OFkq_Ml$wUpdf!8E%HO^+*| zFeOWxu2A?kmT??iQd?F?UCtq+&bJ=io4yo$)!)tA=o?Id0;0LN8jPW!W(RXV%hsLQd`E$urtIKOB zPzUSHk3);hCr2WtA?9G=yUiq89>n*KX%0N~ zN$p?u1Na*U=Ow}F;xLDC&>v>0KZx48I1iTN0PS=FO^tM13{;XMFz~tIYgiH%(#Fpl z!lOkA2DL@9lpY#8Ad~N*B5Tco2O;p`h^+Ip#=>YmPQ0@lipB4R;P)pmk9sGwXH#iSRhP>gv7J6*}1}XtKoo zS^6Y5t8nYKV!F9WsH?SDn3p5NgCj%5I3&F}*>ZdKx}Q4n#(nxv!uDs8%4n>YMl%JZ zD#0g@MT6R}RZxw|6waw^x^oj)O!&6)q*PftYd>IG8@g1Lt=N~%=(kyR9dP~uP)h@| z1Ourw4gE{IKsRh;bkG6-06UYqH%J2a0+R$dGXW`+I5;%{1CwqzH6o`e003@pZe=cT bZf8(S1qJ{B000F51pp2K005Ua00000%f6MD diff --git a/css/green/style.css b/css/green/style.css index 1df236f2..cccb61d9 100644 --- a/css/green/style.css +++ b/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); } \ No newline at end of file diff --git a/css/ui/style.css b/css/ui/style.css index 84b02b53..4f9b1e11 100644 --- a/css/ui/style.css +++ b/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); } \ No newline at end of file diff --git a/docs/example-widget-filter-custom.html b/docs/example-widget-filter-custom.html new file mode 100644 index 00000000..67cc3598 --- /dev/null +++ b/docs/example-widget-filter-custom.html @@ -0,0 +1,335 @@ + + + + + jQuery plugin: Tablesorter 2.0 - Custom Filter Widget + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +

+ NOTE! + Custom filter widget option filter_functions was added in version 2.3.6: +

    +
  • Default Select - See the "First Name" column below. +
      +
    • To enable this type of select, set the filter_functions option for the column to true, and/or add a "filter-select" class to the column header cell.
    • +
    • The default option text, "Select a name", is obtained from the header data-placeholder attribute of the column header cell. And when active, it will show all table rows.
    • +
    • 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.
    • +
    • Select options are automatically sorted.
    • +
    +
  • +
  • Custom Select - See the "Total" column. +
      +
    • To enable this type of select, add your custom options within the filter_functions option.
    • +
    • 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.
    • +
    • See the filter function information below.
    • +
    +
  • +
  • Custom Filter Function - See the "Last Name" column. +
      +
    • To enable this type of filter, add your custom function to the filter_functions option following the example below.
    • +
    • 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 filter_searchDelay option to be a bit longer.
    • +
    • Also, the example only checks for an exact match (===) meaning the filter_ignoreCase option is ignored, but other comparisons can be made using regex and the insensitive "i" flag.
    • +
    • See the filter function information below.
    • +
    +
  • + +
  • Filter function information: +
      +
    • The custom function must return a boolean value. If true is returned, the row will be shown if all other filters match; and if false is returned, the row will be hidden.
    • +
    • The exact text (e) of the table cell is a variable passed to the function. Note that numbers will need to be parsed to make comparisons.
    • +
    • Normalized table cell data (n) is the next varibale passed to the function. +
        +
      • 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.
      • +
      • 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.
      • +
      • The data will be in lower-case if the filter_ignoreCase option is true.
      • +
      • Dates like in the last column of the table below will store the time in seconds since 1970 (using javascript's .getTime() function).
      • +
      • The percentage column will only store the number and not percentage sign.
      • +
      +
    • +
    • The filter input value (f) 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.
    • +
    • The column index (i) might be useful for obtaining more information from header, or something.
    • +
    +
  • +
+

+ +

Demo

+ filter_startsWith : false (if true, search from beginning of cell content only)
+ filter_ignoreCase : true (if false, the search will be case sensitive) + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
First Name Last NameCityAgeTotalDiscountDate
AaronJohnson SrAtlanta35$5.9522%Jun 26, 2004 7:22 AM
AaronJohnsonYuma12$2.995%Aug 21, 2009 12:21 PM
ClarkHenry JrTampa51$42.2918%Oct 13, 2000 1:15 PM
PeterHenryNew York28$9.9920%Jul 6, 2006 8:14 AM
JohnHoodBoston33$19.9925%Dec 10, 2002 5:14 AM
ClarkKent SrLos Angeles18$15.8944%Jan 12, 2003 11:14 AM
JohnKent EsqSeattle45$153.1944%Jan 18, 2021 9:12 AM
PeterJohnsMilwaukee13$5.294%Jan 8, 2012 5:11 PM
AaronEvanChicago24$14.1914%Jan 14, 2004 11:23 AM
BruceEvansUpland22$13.1911%Jan 18, 2007 9:12 AM
ClarkMcMastersPheonix18$55.2015%Feb 12, 2010 7:23 PM
DennisMastersIndianapolis65$123.0032%Jan 20, 2001 1:12 PM
JohnHoodFort Worth25$22.0917%Jun 11, 2011 10:55 AM
+ +

Javascript

+
+

+	
+ +

HTML

+
+

+	
+ + + +
+ + + + diff --git a/docs/example-widget-filter.html b/docs/example-widget-filter.html index 4e32f0f7..a4bd7377 100644 --- a/docs/example-widget-filter.html +++ b/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 }); }); @@ -92,6 +95,20 @@ $(function(){

NOTE!

    +
  • In version 2.3.6, these changes were made: +
      +
    • Include filter input boxes placeholder text by adding data-placeholder to the column header cell; e.g. data-placeholder="First Name". See the examples in the HTML code block below.
    • +
    • 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 Clark" to only find Clark and not Brandon Clark.
    • +
    • Wild cards added: +
        +
      • ? (question mark) finds any single non-space character.
        In the discount column, adding 1?% in the filter will find all percentages between "10%" and "19%". In the last column, J?n will find "Jun" and "Jan".
      • +
      • * (asterisk) finds multiple non-space characters.
        In the first column below Enter Br* will find multiple names starting with "Br". Now add a space at the end, and "Bruce" will not be included in the results.
      • +
      +
    • +
    • Regex method added. Use standard regex within the filter to filter the columns. For example enter /20[1-9]\d/ or /20[^0]\d/ in the last column to find all dates greater than 2009.
    • +
    • Added filter_functions option which allows you to add a custom filter function for a column or to a dropdown list. Please see the jQuery filter widget, advanced demo for more details.
    • +
    +
  • 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.
  • In versions 2.3+, the filter widget can be disabled using any of the following methods, in order of priority:
      @@ -120,18 +137,18 @@ $(function(){
      - + - - + + - - + + @@ -146,7 +163,7 @@ $(function(){ - + @@ -183,14 +200,14 @@ $(function(){ - + - + @@ -202,7 +219,7 @@ $(function(){ - + @@ -223,7 +240,7 @@ $(function(){ - + @@ -279,7 +296,7 @@ table.tablesorter thead tr.filters input.disabled { diff --git a/docs/index.html b/docs/index.html index b5346472..77013c2e 100644 --- a/docs/index.html +++ b/docs/index.html @@ -288,6 +288,7 @@
    • Applying widgets
    • Columns widget (v2.0.17)
    • Filter widget (v2.0.18)
    • +
    • Filter widget, custom New! v2.3.6
    • jQuery UI theme widget (v2.0.9)
    • Resizable Columns widget (v2.0.23.1)
    • Save sort widget (v2.0.27)
    • @@ -678,6 +679,22 @@ + + + + + + + + @@ -1319,6 +1336,113 @@ $(function(){ + + + + + + + diff --git a/js/jquery.tablesorter.js b/js/jquery.tablesorter.js index 2dcb9575..0932000a 100644 --- a/js/jquery.tablesorter.js +++ b/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 = { diff --git a/js/jquery.tablesorter.min.js b/js/jquery.tablesorter.min.js index 4627a8c4..7a137ccc 100644 --- a/js/jquery.tablesorter.min.js +++ b/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'+this.innerHTML+"";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;c1&&d.length){for(g=0;g");$("tr:first td",a.tBodies[0]).each(function(){b.append($("").css("width",$(this).width()))});$(a).prepend(b)}}function updateHeaderSortCount(a,b){var c,d,e,f=a.config,g=b.length;for(c=0;ck){return 1}}o=Math.max(h.length,j.length);for(n=0;nm){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 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=$("x")[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;h1){for(h=1;h1){for(h=1;h0){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;b1){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'+this.innerHTML+"";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;c1&&d.length){for(g=0;g");$("tr:first td",a.tBodies[0]).each(function(){b.append($("").css("width",$(this).width()))});$(a).prepend(b)}}function updateHeaderSortCount(a,b){var c,d,e,f=a.config,g=b.length;for(c=0;ck){return 1}}o=Math.max(h.length,j.length);for(n=0;nm){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 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=$("x")[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;h1){for(h=1;h1){for(h=1;h0){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;b1){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) diff --git a/js/jquery.tablesorter.widgets.js b/js/jquery.tablesorter.widgets.js index 466d05f6..3bd09116 100644 --- a/js/jquery.tablesorter.widgets.js +++ b/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 = ''; + 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 += ''; + } + $t.find('thead').find('select.' + css + '[data-col="' + i + '"]').append(o); }; if (c.debug) { time = new Date(); } for (i=0; i < cols; i++){ - fr += ''; } $t - .find('thead').eq(0).append(fr += '') - .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 += '') + .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 === '' ? '' : ''; + fr += ''; + } + } + $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').wrapInner('
      ').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',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;db.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
      ').wrapInner('
      ')}).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').wrapInner('
      ').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',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'+(b(k.headerList[a]).attr("data-placeholder")||"")+"";for(d=0;d'+f[d]+"";u.find("thead").find("select."+s+'[data-col="'+a+'"]').append(c)};k.debug&&(v=new Date);for(a=0;a":">")+"";u.find("thead").eq(0).append(n+="").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?"":"",n+="");u.find("thead").find("select."+s+'[data-col="'+a+'"]').append(n)}for(a=0;ab.top&&c
      ').wrapInner('
      ')}).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
      First NameFirst Name Last Name Age TotalDiscount DateDiscount Date
      PhilipJohnsonPhilip AaronJohnson Sr Esq 25 $5.95 22%Aug 21, 2009 12:21 PM
      BrandonBrandon Clark Henry Jr 51 $42.2945 $153.19 44%Jan 18, 2001 9:12 AMJan 18, 2021 9:12 AM
      Alex Dumass 13 $5.292%4% Jan 8, 2012 5:11 PM
      Jan 14, 2004 11:23 AM
      BruceBruce Lee Evans 22 $13.1965 $123.00 32%Jan 22, 2001 1:12 PMJan 20, 2001 1:12 PM
      Martha
      initWidgetsBooleantrueApply widgets after table initializes New! v2.3.5. +
      + When true, all widgets set by the widgets option will apply after tablesorter has initialized, this is the normal behavior.
      +
      + If false, the each widget set by the widgets 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.
      +
      + 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. +
      +
      onRenderHeader FunctionExample
      filter_functionsObjectnull + Customize the filter widget by adding a select dropdown with content, custom options or custom filter functions. New! v2.3.6 +
      +
      + Use the "filter_functions" option in three different ways: +
      +
        +
      • + Make a select dropdown list of all column contents. Repeated content will be combined. +
        $(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
        +      }
        +    }
        +  });
        +});
        + Alternately, instead of setting the column filter funtion to true, give the column header a class name of "filter-select". See the demo.

        +
      • +
      • + 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. + +

        Regex example

        +
        $(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); }
        +        }
        +      }
        +    }
        +  });
        +});
        +

        Comparison example

        +
        $(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; }
        +        }
        +      }
        +    }
        +  });
        +});
        + Note: if the filter_ignoreCase option is true, it DOES alter the normalized value (n) by making it all lower case.

        +
      • +
      • + Make a custom filter for the column. +
        $(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;
        +        }
        +      }
        +    }
        +  });
        +});
        + Note: if the filter_ignoreCase option is true, it DOES alter the normalized value (n) by making it all lower case.

        +
      • +
      +
      +
      Example
      filter_searchDelay
      ' : '>') + '