jquery-tablesorter 1.18.1 → 1.18.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +3 -4
- data/lib/jquery-tablesorter/version.rb +1 -1
- data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.combined.js +218 -155
- data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.js +79 -43
- data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.widgets.js +139 -112
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-columnSelector.js +6 -4
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-filter.js +138 -111
- metadata +2 -2
| @@ -1,4 +1,4 @@ | |
| 1 | 
            -
            /* Widget: columnSelector (responsive table widget) - updated 8/ | 
| 1 | 
            +
            /* Widget: columnSelector (responsive table widget) - updated 8/23/2015 (v2.23.2) *//*
         | 
| 2 2 | 
             
             * Requires tablesorter v2.8+ and jQuery 1.7+
         | 
| 3 3 | 
             
             * by Justin Hallett & Rob Garrison
         | 
| 4 4 | 
             
             */
         | 
| @@ -224,7 +224,7 @@ | |
| 224 224 | 
             
            			}
         | 
| 225 225 | 
             
            			// trigger columnUpdate if auto is true (it gets skipped in updateCols()
         | 
| 226 226 | 
             
            			if (colSel.auto) {
         | 
| 227 | 
            -
            				c.$table.trigger( | 
| 227 | 
            +
            				c.$table.trigger(wo.columnSelector_updated);
         | 
| 228 228 | 
             
            			}
         | 
| 229 229 | 
             
            		},
         | 
| 230 230 |  | 
| @@ -299,7 +299,7 @@ | |
| 299 299 | 
             
            			if (wo.columnSelector_saveColumns && ts.storage) {
         | 
| 300 300 | 
             
            				ts.storage( c.$table[0], 'tablesorter-columnSelector', colSel.states );
         | 
| 301 301 | 
             
            			}
         | 
| 302 | 
            -
            			c.$table.trigger( | 
| 302 | 
            +
            			c.$table.trigger(wo.columnSelector_updated);
         | 
| 303 303 | 
             
            		},
         | 
| 304 304 |  | 
| 305 305 | 
             
            		attachTo : function(table, elm) {
         | 
| @@ -370,7 +370,9 @@ | |
| 370 370 | 
             
            			columnSelector_priority : 'data-priority',
         | 
| 371 371 | 
             
            			// class name added to checked checkboxes - this fixes an issue with Chrome not updating FontAwesome
         | 
| 372 372 | 
             
            			// applied icons; use this class name (input.checked) instead of input:checked
         | 
| 373 | 
            -
            			columnSelector_cssChecked : 'checked'
         | 
| 373 | 
            +
            			columnSelector_cssChecked : 'checked',
         | 
| 374 | 
            +
            			// event triggered when columnSelector completes
         | 
| 375 | 
            +
            			columnSelector_updated : 'columnUpdate'
         | 
| 374 376 |  | 
| 375 377 | 
             
            		},
         | 
| 376 378 | 
             
            		init: function(table, thisWidget, c, wo) {
         | 
| @@ -1,11 +1,12 @@ | |
| 1 | 
            -
            /*! Widget: filter - updated 8/ | 
| 1 | 
            +
            /*! Widget: filter - updated 8/23/2015 (v2.23.2) *//*
         | 
| 2 2 | 
             
             * Requires tablesorter v2.8+ and jQuery 1.7+
         | 
| 3 3 | 
             
             * by Rob Garrison
         | 
| 4 4 | 
             
             */
         | 
| 5 5 | 
             
            ;( function ( $ ) {
         | 
| 6 6 | 
             
            	'use strict';
         | 
| 7 | 
            -
            	var  | 
| 8 | 
            -
             | 
| 7 | 
            +
            	var tsf,
         | 
| 8 | 
            +
            		ts = $.tablesorter || {},
         | 
| 9 | 
            +
            		tscss = ts.css;
         | 
| 9 10 |  | 
| 10 11 | 
             
            	$.extend( tscss, {
         | 
| 11 12 | 
             
            		filterRow      : 'tablesorter-filter-row',
         | 
| @@ -49,7 +50,7 @@ | |
| 49 50 | 
             
            		},
         | 
| 50 51 | 
             
            		format: function( table, c, wo ) {
         | 
| 51 52 | 
             
            			if ( !c.$table.hasClass( 'hasFilters' ) ) {
         | 
| 52 | 
            -
            				 | 
| 53 | 
            +
            				tsf.init( table, c, wo );
         | 
| 53 54 | 
             
            			}
         | 
| 54 55 | 
             
            		},
         | 
| 55 56 | 
             
            		remove: function( table, c, wo, refreshing ) {
         | 
| @@ -61,7 +62,7 @@ | |
| 61 62 | 
             
            			$table
         | 
| 62 63 | 
             
            				.removeClass( 'hasFilters' )
         | 
| 63 64 | 
             
            				// add .tsfilter namespace to all BUT search
         | 
| 64 | 
            -
            				.unbind( events.replace(  | 
| 65 | 
            +
            				.unbind( events.replace( ts.regex.spaces, ' ' ) )
         | 
| 65 66 | 
             
            				// remove the filter row even if refreshing, because the column might have been moved
         | 
| 66 67 | 
             
            				.find( '.' + tscss.filterRow ).remove();
         | 
| 67 68 | 
             
            			if ( refreshing ) { return; }
         | 
| @@ -76,7 +77,7 @@ | |
| 76 77 | 
             
            		}
         | 
| 77 78 | 
             
            	});
         | 
| 78 79 |  | 
| 79 | 
            -
            	ts.filter = {
         | 
| 80 | 
            +
            	tsf = ts.filter = {
         | 
| 80 81 |  | 
| 81 82 | 
             
            		// regex used in filter 'check' functions - not for general use and not documented
         | 
| 82 83 | 
             
            		regex: {
         | 
| @@ -85,9 +86,13 @@ | |
| 85 86 | 
             
            			filtered  : /filtered/, // filtered (hidden) row class name; updated in the script
         | 
| 86 87 | 
             
            			type      : /undefined|number/, // check type
         | 
| 87 88 | 
             
            			exact     : /(^[\"\'=]+)|([\"\'=]+$)/g, // exact match (allow '==')
         | 
| 88 | 
            -
            			nondigit  : /[^\w,. \-()]/g, // replace non-digits (from digit & currency parser)
         | 
| 89 89 | 
             
            			operators : /[<>=]/g, // replace operators
         | 
| 90 | 
            -
            			query     : '(q|query)' // replace filter queries
         | 
| 90 | 
            +
            			query     : '(q|query)', // replace filter queries
         | 
| 91 | 
            +
            			wild01    : /\?/g, // wild card match 0 or 1
         | 
| 92 | 
            +
            			wild0More : /\*/g, // wild care match 0 or more
         | 
| 93 | 
            +
            			quote     : /\"/g,
         | 
| 94 | 
            +
            			isNeg1    : /(>=?\s*-\d)/,
         | 
| 95 | 
            +
            			isNeg2    : /(<=?\s*\d)/
         | 
| 91 96 | 
             
            		},
         | 
| 92 97 | 
             
            		// function( c, data ) { }
         | 
| 93 98 | 
             
            		// c = table.config
         | 
| @@ -104,27 +109,27 @@ | |
| 104 109 | 
             
            		// data.parsed = array ( by column ) of boolean values ( from filter_useParsedData or 'filter-parsed' class )
         | 
| 105 110 | 
             
            		types: {
         | 
| 106 111 | 
             
            			or : function( c, data, vars ) {
         | 
| 107 | 
            -
            				if (  | 
| 112 | 
            +
            				if ( tsf.regex.orTest.test( data.iFilter ) || tsf.regex.orSplit.test( data.filter ) ) {
         | 
| 108 113 | 
             
            					var indx, filterMatched, query, regex,
         | 
| 109 114 | 
             
            						// duplicate data but split filter
         | 
| 110 115 | 
             
            						data2 = $.extend( {}, data ),
         | 
| 111 116 | 
             
            						index = data.index,
         | 
| 112 117 | 
             
            						parsed = data.parsed[ index ],
         | 
| 113 | 
            -
            						filter = data.filter.split(  | 
| 114 | 
            -
            						iFilter = data.iFilter.split(  | 
| 118 | 
            +
            						filter = data.filter.split( tsf.regex.orSplit ),
         | 
| 119 | 
            +
            						iFilter = data.iFilter.split( tsf.regex.orSplit ),
         | 
| 115 120 | 
             
            						len = filter.length;
         | 
| 116 121 | 
             
            					for ( indx = 0; indx < len; indx++ ) {
         | 
| 117 122 | 
             
            						data2.nestedFilters = true;
         | 
| 118 | 
            -
            						data2.filter = '' + (  | 
| 119 | 
            -
            						data2.iFilter = '' + (  | 
| 120 | 
            -
            						query = '(' + (  | 
| 123 | 
            +
            						data2.filter = '' + ( tsf.parseFilter( c, filter[ indx ], index, parsed ) || '' );
         | 
| 124 | 
            +
            						data2.iFilter = '' + ( tsf.parseFilter( c, iFilter[ indx ], index, parsed ) || '' );
         | 
| 125 | 
            +
            						query = '(' + ( tsf.parseFilter( c, data2.filter, index, parsed ) || '' ) + ')';
         | 
| 121 126 | 
             
            						try {
         | 
| 122 127 | 
             
            							// use try/catch, because query may not be a valid regex if "|" is contained within a partial regex search,
         | 
| 123 128 | 
             
            							// e.g "/(Alex|Aar" -> Uncaught SyntaxError: Invalid regular expression: /(/(Alex)/: Unterminated group
         | 
| 124 129 | 
             
            							regex = new RegExp( data.isMatch ? query : '^' + query + '$', c.widgetOptions.filter_ignoreCase ? 'i' : '' );
         | 
| 125 130 | 
             
            							// filterMatched = data2.filter === '' && indx > 0 ? true
         | 
| 126 131 | 
             
            							// look for an exact match with the 'or' unless the 'filter-match' class is found
         | 
| 127 | 
            -
            							filterMatched = regex.test( data2.exact ) ||  | 
| 132 | 
            +
            							filterMatched = regex.test( data2.exact ) || tsf.processTypes( c, data2, vars );
         | 
| 128 133 | 
             
            							if ( filterMatched ) {
         | 
| 129 134 | 
             
            								return filterMatched;
         | 
| 130 135 | 
             
            							}
         | 
| @@ -139,27 +144,27 @@ | |
| 139 144 | 
             
            			},
         | 
| 140 145 | 
             
            			// Look for an AND or && operator ( logical and )
         | 
| 141 146 | 
             
            			and : function( c, data, vars ) {
         | 
| 142 | 
            -
            				if (  | 
| 147 | 
            +
            				if ( tsf.regex.andTest.test( data.filter ) ) {
         | 
| 143 148 | 
             
            					var indx, filterMatched, result, query, regex,
         | 
| 144 149 | 
             
            						// duplicate data but split filter
         | 
| 145 150 | 
             
            						data2 = $.extend( {}, data ),
         | 
| 146 151 | 
             
            						index = data.index,
         | 
| 147 152 | 
             
            						parsed = data.parsed[ index ],
         | 
| 148 | 
            -
            						filter = data.filter.split(  | 
| 149 | 
            -
            						iFilter = data.iFilter.split(  | 
| 153 | 
            +
            						filter = data.filter.split( tsf.regex.andSplit ),
         | 
| 154 | 
            +
            						iFilter = data.iFilter.split( tsf.regex.andSplit ),
         | 
| 150 155 | 
             
            						len = filter.length;
         | 
| 151 156 | 
             
            					for ( indx = 0; indx < len; indx++ ) {
         | 
| 152 157 | 
             
            						data2.nestedFilters = true;
         | 
| 153 | 
            -
            						data2.filter = '' + (  | 
| 154 | 
            -
            						data2.iFilter = '' + (  | 
| 155 | 
            -
            						query = ( '(' + (  | 
| 158 | 
            +
            						data2.filter = '' + ( tsf.parseFilter( c, filter[ indx ], index, parsed ) || '' );
         | 
| 159 | 
            +
            						data2.iFilter = '' + ( tsf.parseFilter( c, iFilter[ indx ], index, parsed ) || '' );
         | 
| 160 | 
            +
            						query = ( '(' + ( tsf.parseFilter( c, data2.filter, index, parsed ) || '' ) + ')' )
         | 
| 156 161 | 
             
            							// replace wild cards since /(a*)/i will match anything
         | 
| 157 | 
            -
            							.replace(  | 
| 162 | 
            +
            							.replace( tsf.regex.wild01, '\\S{1}' ).replace( tsf.regex.wild0More, '\\S*' );
         | 
| 158 163 | 
             
            						try {
         | 
| 159 164 | 
             
            							// use try/catch just in case RegExp is invalid
         | 
| 160 165 | 
             
            							regex = new RegExp( data.isMatch ? query : '^' + query + '$', c.widgetOptions.filter_ignoreCase ? 'i' : '' );
         | 
| 161 166 | 
             
            							// look for an exact match with the 'and' unless the 'filter-match' class is found
         | 
| 162 | 
            -
            							result = ( regex.test( data2.exact ) ||  | 
| 167 | 
            +
            							result = ( regex.test( data2.exact ) || tsf.processTypes( c, data2, vars ) );
         | 
| 163 168 | 
             
            							if ( indx === 0 ) {
         | 
| 164 169 | 
             
            								filterMatched = result;
         | 
| 165 170 | 
             
            							} else {
         | 
| @@ -176,10 +181,10 @@ | |
| 176 181 | 
             
            			},
         | 
| 177 182 | 
             
            			// Look for regex
         | 
| 178 183 | 
             
            			regex: function( c, data ) {
         | 
| 179 | 
            -
            				if (  | 
| 184 | 
            +
            				if ( tsf.regex.regex.test( data.filter ) ) {
         | 
| 180 185 | 
             
            					var matches,
         | 
| 181 186 | 
             
            						// cache regex per column for optimal speed
         | 
| 182 | 
            -
            						regex = data.filter_regexCache[ data.index ] ||  | 
| 187 | 
            +
            						regex = data.filter_regexCache[ data.index ] || tsf.regex.regex.exec( data.filter ),
         | 
| 183 188 | 
             
            						isRegex = regex instanceof RegExp;
         | 
| 184 189 | 
             
            					try {
         | 
| 185 190 | 
             
            						if ( !isRegex ) {
         | 
| @@ -198,18 +203,18 @@ | |
| 198 203 | 
             
            			// Look for operators >, >=, < or <=
         | 
| 199 204 | 
             
            			operators: function( c, data ) {
         | 
| 200 205 | 
             
            				// ignore empty strings... because '' < 10 is true
         | 
| 201 | 
            -
            				if (  | 
| 206 | 
            +
            				if ( tsf.regex.operTest.test( data.iFilter ) && data.iExact !== '' ) {
         | 
| 202 207 | 
             
            					var cachedValue, result, txt,
         | 
| 203 208 | 
             
            						table = c.table,
         | 
| 204 209 | 
             
            						index = data.index,
         | 
| 205 210 | 
             
            						parsed = data.parsed[index],
         | 
| 206 | 
            -
            						query = ts.formatFloat( data.iFilter.replace(  | 
| 211 | 
            +
            						query = ts.formatFloat( data.iFilter.replace( tsf.regex.operators, '' ), table ),
         | 
| 207 212 | 
             
            						parser = c.parsers[index],
         | 
| 208 213 | 
             
            						savedSearch = query;
         | 
| 209 214 | 
             
            					// parse filter value in case we're comparing numbers ( dates )
         | 
| 210 215 | 
             
            					if ( parsed || parser.type === 'numeric' ) {
         | 
| 211 | 
            -
            						txt = $.trim( '' + data.iFilter.replace(  | 
| 212 | 
            -
            						result =  | 
| 216 | 
            +
            						txt = $.trim( '' + data.iFilter.replace( tsf.regex.operators, '' ) );
         | 
| 217 | 
            +
            						result = tsf.parseFilter( c, txt, index, true );
         | 
| 213 218 | 
             
            						query = ( typeof result === 'number' && result !== '' && !isNaN( result ) ) ? result : query;
         | 
| 214 219 | 
             
            					}
         | 
| 215 220 | 
             
            					// iExact may be numeric - see issue #149;
         | 
| @@ -218,13 +223,13 @@ | |
| 218 223 | 
             
            						typeof data.cache !== 'undefined' ) {
         | 
| 219 224 | 
             
            						cachedValue = data.cache;
         | 
| 220 225 | 
             
            					} else {
         | 
| 221 | 
            -
            						txt = isNaN( data.iExact ) ? data.iExact.replace( ts. | 
| 226 | 
            +
            						txt = isNaN( data.iExact ) ? data.iExact.replace( ts.regex.nondigit, '' ) : data.iExact;
         | 
| 222 227 | 
             
            						cachedValue = ts.formatFloat( txt, table );
         | 
| 223 228 | 
             
            					}
         | 
| 224 | 
            -
            					if (  | 
| 225 | 
            -
            						result =  | 
| 226 | 
            -
            					} else if (  | 
| 227 | 
            -
            						result =  | 
| 229 | 
            +
            					if ( tsf.regex.gtTest.test( data.iFilter ) ) {
         | 
| 230 | 
            +
            						result = tsf.regex.gteTest.test( data.iFilter ) ? cachedValue >= query : cachedValue > query;
         | 
| 231 | 
            +
            					} else if ( tsf.regex.ltTest.test( data.iFilter ) ) {
         | 
| 232 | 
            +
            						result = tsf.regex.lteTest.test( data.iFilter ) ? cachedValue <= query : cachedValue < query;
         | 
| 228 233 | 
             
            					}
         | 
| 229 234 | 
             
            					// keep showing all rows if nothing follows the operator
         | 
| 230 235 | 
             
            					if ( !result && savedSearch === '' ) {
         | 
| @@ -236,13 +241,13 @@ | |
| 236 241 | 
             
            			},
         | 
| 237 242 | 
             
            			// Look for a not match
         | 
| 238 243 | 
             
            			notMatch: function( c, data ) {
         | 
| 239 | 
            -
            				if (  | 
| 244 | 
            +
            				if ( tsf.regex.notTest.test( data.iFilter ) ) {
         | 
| 240 245 | 
             
            					var indx,
         | 
| 241 246 | 
             
            						txt = data.iFilter.replace( '!', '' ),
         | 
| 242 | 
            -
            						filter =  | 
| 243 | 
            -
            					if (  | 
| 247 | 
            +
            						filter = tsf.parseFilter( c, txt, data.index, data.parsed[data.index] ) || '';
         | 
| 248 | 
            +
            					if ( tsf.regex.exact.test( filter ) ) {
         | 
| 244 249 | 
             
            						// look for exact not matches - see #628
         | 
| 245 | 
            -
            						filter = filter.replace(  | 
| 250 | 
            +
            						filter = filter.replace( tsf.regex.exact, '' );
         | 
| 246 251 | 
             
            						return filter === '' ? true : $.trim( filter ) !== data.iExact;
         | 
| 247 252 | 
             
            					} else {
         | 
| 248 253 | 
             
            						indx = data.iExact.search( $.trim( filter ) );
         | 
| @@ -254,27 +259,27 @@ | |
| 254 259 | 
             
            			// Look for quotes or equals to get an exact match; ignore type since iExact could be numeric
         | 
| 255 260 | 
             
            			exact: function( c, data ) {
         | 
| 256 261 | 
             
            				/*jshint eqeqeq:false */
         | 
| 257 | 
            -
            				if (  | 
| 258 | 
            -
            					var txt = data.iFilter.replace(  | 
| 259 | 
            -
            						filter =  | 
| 262 | 
            +
            				if ( tsf.regex.exact.test( data.iFilter ) ) {
         | 
| 263 | 
            +
            					var txt = data.iFilter.replace( tsf.regex.exact, '' ),
         | 
| 264 | 
            +
            						filter = tsf.parseFilter( c, txt, data.index, data.parsed[data.index] ) || '';
         | 
| 260 265 | 
             
            					return data.anyMatch ? $.inArray( filter, data.rowArray ) >= 0 : filter == data.iExact;
         | 
| 261 266 | 
             
            				}
         | 
| 262 267 | 
             
            				return null;
         | 
| 263 268 | 
             
            			},
         | 
| 264 269 | 
             
            			// Look for a range ( using ' to ' or ' - ' ) - see issue #166; thanks matzhu!
         | 
| 265 270 | 
             
            			range : function( c, data ) {
         | 
| 266 | 
            -
            				if (  | 
| 271 | 
            +
            				if ( tsf.regex.toTest.test( data.iFilter ) ) {
         | 
| 267 272 | 
             
            					var result, tmp, range1, range2,
         | 
| 268 273 | 
             
            						table = c.table,
         | 
| 269 274 | 
             
            						index = data.index,
         | 
| 270 275 | 
             
            						parsed = data.parsed[index],
         | 
| 271 276 | 
             
            						// make sure the dash is for a range and not indicating a negative number
         | 
| 272 | 
            -
            						query = data.iFilter.split(  | 
| 277 | 
            +
            						query = data.iFilter.split( tsf.regex.toSplit );
         | 
| 273 278 |  | 
| 274 | 
            -
            					tmp = query[0].replace( ts. | 
| 275 | 
            -
            					range1 = ts.formatFloat(  | 
| 276 | 
            -
            					tmp = query[1].replace( ts. | 
| 277 | 
            -
            					range2 = ts.formatFloat(  | 
| 279 | 
            +
            					tmp = query[0].replace( ts.regex.nondigit, '' ) || '';
         | 
| 280 | 
            +
            					range1 = ts.formatFloat( tsf.parseFilter( c, tmp, index, parsed ), table );
         | 
| 281 | 
            +
            					tmp = query[1].replace( ts.regex.nondigit, '' ) || '';
         | 
| 282 | 
            +
            					range2 = ts.formatFloat( tsf.parseFilter( c, tmp, index, parsed ), table );
         | 
| 278 283 | 
             
            					// parse filter value in case we're comparing numbers ( dates )
         | 
| 279 284 | 
             
            					if ( parsed || c.parsers[index].type === 'numeric' ) {
         | 
| 280 285 | 
             
            						result = c.parsers[ index ].format( '' + query[0], table, c.$headers.eq( index ), index );
         | 
| @@ -285,7 +290,7 @@ | |
| 285 290 | 
             
            					if ( ( parsed || c.parsers[ index ].type === 'numeric' ) && !isNaN( range1 ) && !isNaN( range2 ) ) {
         | 
| 286 291 | 
             
            						result = data.cache;
         | 
| 287 292 | 
             
            					} else {
         | 
| 288 | 
            -
            						tmp = isNaN( data.iExact ) ? data.iExact.replace( ts. | 
| 293 | 
            +
            						tmp = isNaN( data.iExact ) ? data.iExact.replace( ts.regex.nondigit, '' ) : data.iExact;
         | 
| 289 294 | 
             
            						result = ts.formatFloat( tmp, table );
         | 
| 290 295 | 
             
            					}
         | 
| 291 296 | 
             
            					if ( range1 > range2 ) {
         | 
| @@ -297,18 +302,18 @@ | |
| 297 302 | 
             
            			},
         | 
| 298 303 | 
             
            			// Look for wild card: ? = single, * = multiple, or | = logical OR
         | 
| 299 304 | 
             
            			wild : function( c, data ) {
         | 
| 300 | 
            -
            				if (  | 
| 305 | 
            +
            				if ( tsf.regex.wildOrTest.test( data.iFilter ) ) {
         | 
| 301 306 | 
             
            					var index = data.index,
         | 
| 302 307 | 
             
            						parsed = data.parsed[ index ],
         | 
| 303 | 
            -
            						query = '' + (  | 
| 308 | 
            +
            						query = '' + ( tsf.parseFilter( c, data.iFilter, index, parsed ) || '' );
         | 
| 304 309 | 
             
            					// look for an exact match with the 'or' unless the 'filter-match' class is found
         | 
| 305 | 
            -
            					if (  | 
| 310 | 
            +
            					if ( !tsf.regex.wildTest.test( query ) && data.nestedFilters ) {
         | 
| 306 311 | 
             
            						query = data.isMatch ? query : '^(' + query + ')$';
         | 
| 307 312 | 
             
            					}
         | 
| 308 313 | 
             
            					// parsing the filter may not work properly when using wildcards =/
         | 
| 309 314 | 
             
            					try {
         | 
| 310 315 | 
             
            						return new RegExp(
         | 
| 311 | 
            -
            							query.replace(  | 
| 316 | 
            +
            							query.replace( tsf.regex.wild01, '\\S{1}' ).replace( tsf.regex.wild0More, '\\S*' ),
         | 
| 312 317 | 
             
            							c.widgetOptions.filter_ignoreCase ? 'i' : ''
         | 
| 313 318 | 
             
            						)
         | 
| 314 319 | 
             
            						.test( data.exact );
         | 
| @@ -320,12 +325,12 @@ | |
| 320 325 | 
             
            			},
         | 
| 321 326 | 
             
            			// fuzzy text search; modified from https://github.com/mattyork/fuzzy ( MIT license )
         | 
| 322 327 | 
             
            			fuzzy: function( c, data ) {
         | 
| 323 | 
            -
            				if (  | 
| 328 | 
            +
            				if ( tsf.regex.fuzzyTest.test( data.iFilter ) ) {
         | 
| 324 329 | 
             
            					var indx,
         | 
| 325 330 | 
             
            						patternIndx = 0,
         | 
| 326 331 | 
             
            						len = data.iExact.length,
         | 
| 327 332 | 
             
            						txt = data.iFilter.slice( 1 ),
         | 
| 328 | 
            -
            						pattern =  | 
| 333 | 
            +
            						pattern = tsf.parseFilter( c, txt, data.index, data.parsed[data.index] ) || '';
         | 
| 329 334 | 
             
            					for ( indx = 0; indx < len; indx++ ) {
         | 
| 330 335 | 
             
            						if ( data.iExact[ indx ] === pattern[ patternIndx ] ) {
         | 
| 331 336 | 
             
            							patternIndx += 1;
         | 
| @@ -348,7 +353,7 @@ | |
| 348 353 | 
             
            			}, ts.language );
         | 
| 349 354 |  | 
| 350 355 | 
             
            			var options, string, txt, $header, column, filters, val, fxn, noSelect,
         | 
| 351 | 
            -
            				regex =  | 
| 356 | 
            +
            				regex = tsf.regex;
         | 
| 352 357 | 
             
            			c.$table.addClass( 'hasFilters' );
         | 
| 353 358 |  | 
| 354 359 | 
             
            			// define timers so using clearTimeout won't cause an undefined error
         | 
| @@ -359,7 +364,7 @@ | |
| 359 364 | 
             
            			wo.filter_anyColumnSelector = '[data-column="all"],[data-column="any"]';
         | 
| 360 365 | 
             
            			wo.filter_multipleColumnSelector = '[data-column*="-"],[data-column*=","]';
         | 
| 361 366 |  | 
| 362 | 
            -
            			val = '\\{' +  | 
| 367 | 
            +
            			val = '\\{' + tsf.regex.query + '\\}';
         | 
| 363 368 | 
             
            			$.extend( regex, {
         | 
| 364 369 | 
             
            				child : new RegExp( c.cssChildRow ),
         | 
| 365 370 | 
             
            				filtered : new RegExp( wo.filter_filteredRow ),
         | 
| @@ -368,9 +373,20 @@ | |
| 368 373 | 
             
            				toSplit : new RegExp( '(?:\\s+(?:-|' + ts.language.to + ')\\s+)', 'gi' ),
         | 
| 369 374 | 
             
            				andTest : new RegExp( '\\s+(' + ts.language.and + '|&&)\\s+', 'i' ),
         | 
| 370 375 | 
             
            				andSplit : new RegExp( '(?:\\s+(?:' + ts.language.and + '|&&)\\s+)', 'gi' ),
         | 
| 376 | 
            +
            				orTest : /\|/,
         | 
| 371 377 | 
             
            				orSplit : new RegExp( '(?:\\s+(?:' + ts.language.or + ')\\s+|\\|)', 'gi' ),
         | 
| 372 378 | 
             
            				iQuery : new RegExp( val, 'i' ),
         | 
| 373 | 
            -
            				igQuery : new RegExp( val, 'ig' )
         | 
| 379 | 
            +
            				igQuery : new RegExp( val, 'ig' ),
         | 
| 380 | 
            +
            				operTest : /^[<>]=?/,
         | 
| 381 | 
            +
            				gtTest  : />/,
         | 
| 382 | 
            +
            				gteTest : />=/,
         | 
| 383 | 
            +
            				ltTest  : /</,
         | 
| 384 | 
            +
            				lteTest : /<=/,
         | 
| 385 | 
            +
            				notTest : /^\!/,
         | 
| 386 | 
            +
            				wildOrTest : /[\?\*\|]/,
         | 
| 387 | 
            +
            				wildTest : /\?\*/,
         | 
| 388 | 
            +
            				fuzzyTest : /^~/,
         | 
| 389 | 
            +
            				exactTest : /[=\"\|!]/
         | 
| 374 390 | 
             
            			});
         | 
| 375 391 |  | 
| 376 392 | 
             
            			// don't build filter row if columnFilters is false or all columns are set to 'filter-false'
         | 
| @@ -378,7 +394,7 @@ | |
| 378 394 | 
             
            			val = c.$headers.filter( '.filter-false, .parser-false' ).length;
         | 
| 379 395 | 
             
            			if ( wo.filter_columnFilters !== false && val !== c.$headers.length ) {
         | 
| 380 396 | 
             
            				// build filter row
         | 
| 381 | 
            -
            				 | 
| 397 | 
            +
            				tsf.buildRow( table, c, wo );
         | 
| 382 398 | 
             
            			}
         | 
| 383 399 |  | 
| 384 400 | 
             
            			txt = 'addRows updateCell update updateRows updateComplete appendCache filterReset filterEnd search '
         | 
| @@ -391,13 +407,13 @@ | |
| 391 407 | 
             
            				c.$table.find( '.' + tscss.filterRow ).toggleClass( wo.filter_filteredRow, val ); // fixes #450
         | 
| 392 408 | 
             
            				if ( !/(search|filter)/.test( event.type ) ) {
         | 
| 393 409 | 
             
            					event.stopPropagation();
         | 
| 394 | 
            -
            					 | 
| 410 | 
            +
            					tsf.buildDefault( table, true );
         | 
| 395 411 | 
             
            				}
         | 
| 396 412 | 
             
            				if ( event.type === 'filterReset' ) {
         | 
| 397 413 | 
             
            					c.$table.find( '.' + tscss.filter ).add( wo.filter_$externalFilters ).val( '' );
         | 
| 398 | 
            -
            					 | 
| 414 | 
            +
            					tsf.searching( table, [] );
         | 
| 399 415 | 
             
            				} else if ( event.type === 'filterEnd' ) {
         | 
| 400 | 
            -
            					 | 
| 416 | 
            +
            					tsf.buildDefault( table, true );
         | 
| 401 417 | 
             
            				} else {
         | 
| 402 418 | 
             
            					// send false argument to force a new search; otherwise if the filter hasn't changed,
         | 
| 403 419 | 
             
            					// it will return
         | 
| @@ -411,7 +427,7 @@ | |
| 411 427 | 
             
            					// pass true ( skipFirst ) to prevent the tablesorter.setFilters function from skipping the first
         | 
| 412 428 | 
             
            					// input ensures all inputs are updated when a search is triggered on the table
         | 
| 413 429 | 
             
            					// $( 'table' ).trigger( 'search', [...] );
         | 
| 414 | 
            -
            					 | 
| 430 | 
            +
            					tsf.searching( table, filter, true );
         | 
| 415 431 | 
             
            				}
         | 
| 416 432 | 
             
            				return false;
         | 
| 417 433 | 
             
            			});
         | 
| @@ -444,7 +460,7 @@ | |
| 444 460 | 
             
            						noSelect = !( $header.hasClass( 'filter-false' ) || $header.hasClass( 'parser-false' ) );
         | 
| 445 461 | 
             
            						options = '';
         | 
| 446 462 | 
             
            						if ( fxn === true && noSelect ) {
         | 
| 447 | 
            -
            							 | 
| 463 | 
            +
            							tsf.buildSelect( table, column );
         | 
| 448 464 | 
             
            						} else if ( typeof fxn === 'object' && noSelect ) {
         | 
| 449 465 | 
             
            							// add custom drop down list
         | 
| 450 466 | 
             
            							for ( string in fxn ) {
         | 
| @@ -477,7 +493,7 @@ | |
| 477 493 | 
             
            							fxn = $.isFunction( txt ) ? true : ts.getColumnData( table, txt, column );
         | 
| 478 494 | 
             
            							if ( fxn ) {
         | 
| 479 495 | 
             
            								// updating so the extra options are appended
         | 
| 480 | 
            -
            								 | 
| 496 | 
            +
            								tsf.buildSelect( c.table, column, '', true, $header.hasClass( wo.filter_onlyAvail ) );
         | 
| 481 497 | 
             
            							}
         | 
| 482 498 | 
             
            						}
         | 
| 483 499 | 
             
            					}
         | 
| @@ -485,22 +501,22 @@ | |
| 485 501 | 
             
            			}
         | 
| 486 502 | 
             
            			// not really updating, but if the column has both the 'filter-select' class &
         | 
| 487 503 | 
             
            			// filter_functions set to true, it would append the same options twice.
         | 
| 488 | 
            -
            			 | 
| 504 | 
            +
            			tsf.buildDefault( table, true );
         | 
| 489 505 |  | 
| 490 | 
            -
            			 | 
| 506 | 
            +
            			tsf.bindSearch( table, c.$table.find( '.' + tscss.filter ), true );
         | 
| 491 507 | 
             
            			if ( wo.filter_external ) {
         | 
| 492 | 
            -
            				 | 
| 508 | 
            +
            				tsf.bindSearch( table, wo.filter_external );
         | 
| 493 509 | 
             
            			}
         | 
| 494 510 |  | 
| 495 511 | 
             
            			if ( wo.filter_hideFilters ) {
         | 
| 496 | 
            -
            				 | 
| 512 | 
            +
            				tsf.hideFilters( table, c );
         | 
| 497 513 | 
             
            			}
         | 
| 498 514 |  | 
| 499 515 | 
             
            			// show processing icon
         | 
| 500 516 | 
             
            			if ( c.showProcessing ) {
         | 
| 501 517 | 
             
            				txt = 'filterStart filterEnd '.split( ' ' ).join( c.namespace + 'filter ' );
         | 
| 502 518 | 
             
            				c.$table
         | 
| 503 | 
            -
            					.unbind( txt.replace(  | 
| 519 | 
            +
            					.unbind( txt.replace( ts.regex.spaces, ' ' ) )
         | 
| 504 520 | 
             
            					.bind( txt, function( event, columns ) {
         | 
| 505 521 | 
             
            					// only add processing to certain columns to all columns
         | 
| 506 522 | 
             
            					$header = ( columns ) ?
         | 
| @@ -520,11 +536,11 @@ | |
| 520 536 | 
             
            			// add default values
         | 
| 521 537 | 
             
            			txt = 'tablesorter-initialized pagerBeforeInitialized '.split( ' ' ).join( c.namespace + 'filter ' );
         | 
| 522 538 | 
             
            			c.$table
         | 
| 523 | 
            -
            			.unbind( txt.replace(  | 
| 539 | 
            +
            			.unbind( txt.replace( ts.regex.spaces, ' ' ) )
         | 
| 524 540 | 
             
            			.bind( txt, function() {
         | 
| 525 541 | 
             
            				// redefine 'wo' as it does not update properly inside this callback
         | 
| 526 542 | 
             
            				var wo = this.config.widgetOptions;
         | 
| 527 | 
            -
            				filters =  | 
| 543 | 
            +
            				filters = tsf.setDefaults( table, c, wo ) || [];
         | 
| 528 544 | 
             
            				if ( filters.length ) {
         | 
| 529 545 | 
             
            					// prevent delayInit from triggering a cache build if filters are empty
         | 
| 530 546 | 
             
            					if ( !( c.delayInit && filters.join( '' ) === '' ) ) {
         | 
| @@ -535,7 +551,7 @@ | |
| 535 551 | 
             
            				// trigger init after setTimeout to prevent multiple filterStart/End/Init triggers
         | 
| 536 552 | 
             
            				setTimeout( function() {
         | 
| 537 553 | 
             
            					if ( !wo.filter_initialized ) {
         | 
| 538 | 
            -
            						 | 
| 554 | 
            +
            						tsf.filterInitComplete( c );
         | 
| 539 555 | 
             
            					}
         | 
| 540 556 | 
             
            				}, 100 );
         | 
| 541 557 | 
             
            			});
         | 
| @@ -543,7 +559,7 @@ | |
| 543 559 | 
             
            			if ( c.pager && c.pager.initialized && !wo.filter_initialized ) {
         | 
| 544 560 | 
             
            				c.$table.trigger( 'filterFomatterUpdate' );
         | 
| 545 561 | 
             
            				setTimeout( function() {
         | 
| 546 | 
            -
            					 | 
| 562 | 
            +
            					tsf.filterInitComplete( c );
         | 
| 547 563 | 
             
            				}, 100 );
         | 
| 548 564 | 
             
            			}
         | 
| 549 565 | 
             
            		},
         | 
| @@ -564,7 +580,7 @@ | |
| 564 580 | 
             
            				completed = function() {
         | 
| 565 581 | 
             
            					wo.filter_initialized = true;
         | 
| 566 582 | 
             
            					c.$table.trigger( 'filterInit', c );
         | 
| 567 | 
            -
            					 | 
| 583 | 
            +
            					tsf.findRows( c.table, c.$table.data( 'lastSearch' ) || [] );
         | 
| 568 584 | 
             
            				};
         | 
| 569 585 | 
             
            			if ( $.isEmptyObject( wo.filter_formatter ) ) {
         | 
| 570 586 | 
             
            				completed();
         | 
| @@ -716,7 +732,7 @@ | |
| 716 732 | 
             
            			// use data attribute instead of jQuery data since the head is cloned without including
         | 
| 717 733 | 
             
            			// the data/binding
         | 
| 718 734 | 
             
            			.attr( 'data-lastSearchTime', new Date().getTime() )
         | 
| 719 | 
            -
            			.unbind( tmp.replace(  | 
| 735 | 
            +
            			.unbind( tmp.replace( ts.regex.spaces, ' ' ) )
         | 
| 720 736 | 
             
            			// include change for select - fixes #473
         | 
| 721 737 | 
             
            			.bind( 'keyup' + namespace, function( event ) {
         | 
| 722 738 | 
             
            				$( this ).attr( 'data-lastSearchTime', new Date().getTime() );
         | 
| @@ -736,17 +752,18 @@ | |
| 736 752 | 
             
            					return;
         | 
| 737 753 | 
             
            				}
         | 
| 738 754 | 
             
            				// change event = no delay; last true flag tells getFilters to skip newest timed input
         | 
| 739 | 
            -
            				 | 
| 755 | 
            +
            				tsf.searching( table, true, true );
         | 
| 740 756 | 
             
            			})
         | 
| 741 757 | 
             
            			.bind( 'search change keypress '.split( ' ' ).join( namespace + ' ' ), function( event ) {
         | 
| 742 | 
            -
            				 | 
| 758 | 
            +
            				// don't get cached data, in case data-column changes dynamically
         | 
| 759 | 
            +
            				var column = parseInt( $( this ).attr( 'data-column' ), 10 );
         | 
| 743 760 | 
             
            				// don't allow 'change' event to process if the input value is the same - fixes #685
         | 
| 744 761 | 
             
            				if ( event.which === 13 || event.type === 'search' ||
         | 
| 745 762 | 
             
            					event.type === 'change' && this.value !== c.lastSearch[column] ) {
         | 
| 746 763 | 
             
            					event.preventDefault();
         | 
| 747 764 | 
             
            					// init search with no delay
         | 
| 748 765 | 
             
            					$( this ).attr( 'data-lastSearchTime', new Date().getTime() );
         | 
| 749 | 
            -
            					 | 
| 766 | 
            +
            					tsf.searching( table, false, true );
         | 
| 750 767 | 
             
            				}
         | 
| 751 768 | 
             
            			});
         | 
| 752 769 | 
             
            		},
         | 
| @@ -756,11 +773,11 @@ | |
| 756 773 | 
             
            			if ( typeof filter === 'undefined' || filter === true ) {
         | 
| 757 774 | 
             
            				// delay filtering
         | 
| 758 775 | 
             
            				wo.searchTimer = setTimeout( function() {
         | 
| 759 | 
            -
            					 | 
| 776 | 
            +
            					tsf.checkFilters( table, filter, skipFirst );
         | 
| 760 777 | 
             
            				}, wo.filter_liveSearch ? wo.filter_searchDelay : 10 );
         | 
| 761 778 | 
             
            			} else {
         | 
| 762 779 | 
             
            				// skip delay
         | 
| 763 | 
            -
            				 | 
| 780 | 
            +
            				tsf.checkFilters( table, filter, skipFirst );
         | 
| 764 781 | 
             
            			}
         | 
| 765 782 | 
             
            		},
         | 
| 766 783 | 
             
            		checkFilters: function( table, filter, skipFirst ) {
         | 
| @@ -774,7 +791,7 @@ | |
| 774 791 | 
             
            				// update cache if delayInit set & pager has initialized ( after user initiates a search )
         | 
| 775 792 | 
             
            				if ( c.delayInit && c.pager && c.pager.initialized ) {
         | 
| 776 793 | 
             
            					c.$table.trigger( 'updateCache', [ function() {
         | 
| 777 | 
            -
            						 | 
| 794 | 
            +
            						tsf.checkFilters( table, false, skipFirst );
         | 
| 778 795 | 
             
            					} ] );
         | 
| 779 796 | 
             
            				}
         | 
| 780 797 | 
             
            				return;
         | 
| @@ -805,11 +822,11 @@ | |
| 805 822 | 
             
            			if ( c.showProcessing ) {
         | 
| 806 823 | 
             
            				// give it time for the processing icon to kick in
         | 
| 807 824 | 
             
            				setTimeout( function() {
         | 
| 808 | 
            -
            					 | 
| 825 | 
            +
            					tsf.findRows( table, filters, combinedFilters );
         | 
| 809 826 | 
             
            					return false;
         | 
| 810 827 | 
             
            				}, 30 );
         | 
| 811 828 | 
             
            			} else {
         | 
| 812 | 
            -
            				 | 
| 829 | 
            +
            				tsf.findRows( table, filters, combinedFilters );
         | 
| 813 830 | 
             
            				return false;
         | 
| 814 831 | 
             
            			}
         | 
| 815 832 | 
             
            		},
         | 
| @@ -852,8 +869,8 @@ | |
| 852 869 | 
             
            		},
         | 
| 853 870 | 
             
            		defaultFilter: function( filter, mask ) {
         | 
| 854 871 | 
             
            			if ( filter === '' ) { return filter; }
         | 
| 855 | 
            -
            			var regex =  | 
| 856 | 
            -
            				maskLen = mask.match(  | 
| 872 | 
            +
            			var regex = tsf.regex.iQuery,
         | 
| 873 | 
            +
            				maskLen = mask.match( tsf.regex.igQuery ).length,
         | 
| 857 874 | 
             
            				query = maskLen > 1 ? $.trim( filter ).split( /\s/ ) : [ $.trim( filter ) ],
         | 
| 858 875 | 
             
            				len = query.length - 1,
         | 
| 859 876 | 
             
            				indx = 0,
         | 
| @@ -889,7 +906,10 @@ | |
| 889 906 | 
             
            				// & don't target 'all' column inputs if they don't exist
         | 
| 890 907 | 
             
            				targets = wo.filter_initialized || !$input.filter( wo.filter_anyColumnSelector ).length,
         | 
| 891 908 | 
             
            				columns = [],
         | 
| 892 | 
            -
            				val = $.trim(  | 
| 909 | 
            +
            				val = $.trim( tsf.getLatestSearch( $input ).attr( 'data-column' ) || '' );
         | 
| 910 | 
            +
            			if ( !/[,-]/.test(val) && val.length === 1 ) {
         | 
| 911 | 
            +
            				return parseInt( val, 10 );
         | 
| 912 | 
            +
            			}
         | 
| 893 913 | 
             
            			// process column range
         | 
| 894 914 | 
             
            			if ( targets && /-/.test( val ) ) {
         | 
| 895 915 | 
             
            				ranges = val.match( /(\d+)\s*-\s*(\d+)/g );
         | 
| @@ -936,9 +956,9 @@ | |
| 936 956 | 
             
            			var ffxn,
         | 
| 937 957 | 
             
            				filterMatched = null,
         | 
| 938 958 | 
             
            				matches = null;
         | 
| 939 | 
            -
            			for ( ffxn in  | 
| 959 | 
            +
            			for ( ffxn in tsf.types ) {
         | 
| 940 960 | 
             
            				if ( $.inArray( ffxn, vars.excludeMatch ) < 0 && matches === null ) {
         | 
| 941 | 
            -
            					matches =  | 
| 961 | 
            +
            					matches = tsf.types[ffxn]( c, data, vars );
         | 
| 942 962 | 
             
            					if ( matches !== null ) {
         | 
| 943 963 | 
             
            						filterMatched = matches;
         | 
| 944 964 | 
             
            					}
         | 
| @@ -947,16 +967,23 @@ | |
| 947 967 | 
             
            			return filterMatched;
         | 
| 948 968 | 
             
            		},
         | 
| 949 969 | 
             
            		processRow: function( c, data, vars ) {
         | 
| 950 | 
            -
            			var  | 
| 970 | 
            +
            			var hasSelect, result, val, filterMatched,
         | 
| 951 971 | 
             
            				fxn, ffxn, txt,
         | 
| 952 | 
            -
            				regex =  | 
| 972 | 
            +
            				regex = tsf.regex,
         | 
| 953 973 | 
             
            				wo = c.widgetOptions,
         | 
| 954 | 
            -
            				showRow = true | 
| 974 | 
            +
            				showRow = true,
         | 
| 975 | 
            +
             | 
| 976 | 
            +
            				// if wo.filter_$anyMatch data-column attribute is changed dynamically
         | 
| 977 | 
            +
            				// we don't want to do an "anyMatch" search on one column using data
         | 
| 978 | 
            +
            				// for the entire row - see #998
         | 
| 979 | 
            +
            				columnIndex = wo.filter_$anyMatch && wo.filter_$anyMatch.length ?
         | 
| 980 | 
            +
            					// look for multiple columns '1-3,4-6,8'
         | 
| 981 | 
            +
            					tsf.multipleColumns( c, wo.filter_$anyMatch ) :
         | 
| 982 | 
            +
            					[];
         | 
| 983 | 
            +
             | 
| 955 984 | 
             
            			data.$cells = data.$row.children();
         | 
| 956 985 |  | 
| 957 | 
            -
            			if ( data.anyMatchFlag ) {
         | 
| 958 | 
            -
            				// look for multiple columns '1-3,4-6,8'
         | 
| 959 | 
            -
            				columnIndex = ts.filter.multipleColumns( c, wo.filter_$anyMatch );
         | 
| 986 | 
            +
            			if ( data.anyMatchFlag && columnIndex.length > 1 ) {
         | 
| 960 987 | 
             
            				data.anyMatch = true;
         | 
| 961 988 | 
             
            				data.isMatch = true;
         | 
| 962 989 | 
             
            				data.rowArray = data.$cells.map( function( i ) {
         | 
| @@ -980,7 +1007,7 @@ | |
| 980 1007 | 
             
            				data.cache = data.cacheArray.slice( 0, -1 ).join( ' ' );
         | 
| 981 1008 |  | 
| 982 1009 | 
             
            				vars.excludeMatch = vars.noAnyMatch;
         | 
| 983 | 
            -
            				filterMatched =  | 
| 1010 | 
            +
            				filterMatched = tsf.processTypes( c, data, vars );
         | 
| 984 1011 |  | 
| 985 1012 | 
             
            				if ( filterMatched !== null ) {
         | 
| 986 1013 | 
             
            					showRow = filterMatched;
         | 
| @@ -1041,7 +1068,7 @@ | |
| 1041 1068 |  | 
| 1042 1069 | 
             
            					val = true;
         | 
| 1043 1070 | 
             
            					if ( wo.filter_defaultFilter && regex.iQuery.test( vars.defaultColFilter[ columnIndex ] ) ) {
         | 
| 1044 | 
            -
            						data.filter =  | 
| 1071 | 
            +
            						data.filter = tsf.defaultFilter( data.filter, vars.defaultColFilter[ columnIndex ] );
         | 
| 1045 1072 | 
             
            						// val is used to indicate that a filter select is using a default filter;
         | 
| 1046 1073 | 
             
            						// so we override the exact & partial matches
         | 
| 1047 1074 | 
             
            						val = false;
         | 
| @@ -1072,13 +1099,13 @@ | |
| 1072 1099 | 
             
            					if ( filterMatched === null ) {
         | 
| 1073 1100 | 
             
            						// cycle through the different filters
         | 
| 1074 1101 | 
             
            						// filters return a boolean or null if nothing matches
         | 
| 1075 | 
            -
            						filterMatched =  | 
| 1102 | 
            +
            						filterMatched = tsf.processTypes( c, data, vars );
         | 
| 1076 1103 | 
             
            						if ( filterMatched !== null ) {
         | 
| 1077 1104 | 
             
            							result = filterMatched;
         | 
| 1078 1105 | 
             
            						// Look for match, and add child row data for matching
         | 
| 1079 1106 | 
             
            						} else {
         | 
| 1080 1107 | 
             
            							txt = ( data.iExact + data.childRowText )
         | 
| 1081 | 
            -
            								.indexOf(  | 
| 1108 | 
            +
            								.indexOf( tsf.parseFilter( c, data.iFilter, columnIndex, data.parsed[ columnIndex ] ) );
         | 
| 1082 1109 | 
             
            							result = ( ( !wo.filter_startsWith && txt >= 0 ) || ( wo.filter_startsWith && txt === 0 ) );
         | 
| 1083 1110 | 
             
            						}
         | 
| 1084 1111 | 
             
            					} else {
         | 
| @@ -1098,7 +1125,7 @@ | |
| 1098 1125 | 
             
            				isChild, childRow, lastSearch, showRow, time, val, indx,
         | 
| 1099 1126 | 
             
            				notFiltered, searchFiltered, query, injected, res, id, txt,
         | 
| 1100 1127 | 
             
            				storedFilters = $.extend( [], filters ),
         | 
| 1101 | 
            -
            				regex =  | 
| 1128 | 
            +
            				regex = tsf.regex,
         | 
| 1102 1129 | 
             
            				c = table.config,
         | 
| 1103 1130 | 
             
            				wo = c.widgetOptions,
         | 
| 1104 1131 | 
             
            				// data object passed to filters; anyMatch is a flag for the filters
         | 
| @@ -1175,7 +1202,7 @@ | |
| 1175 1202 | 
             
            						data.anyMatchFlag = true;
         | 
| 1176 1203 | 
             
            						data.anyMatchFilter = '' + (
         | 
| 1177 1204 | 
             
            							filters[ c.columns ] ||
         | 
| 1178 | 
            -
            							wo.filter_$anyMatch &&  | 
| 1205 | 
            +
            							wo.filter_$anyMatch && tsf.getLatestSearch( wo.filter_$anyMatch ).val() ||
         | 
| 1179 1206 | 
             
            							''
         | 
| 1180 1207 | 
             
            						);
         | 
| 1181 1208 | 
             
            						if ( wo.filter_columnAnyMatch ) {
         | 
| @@ -1217,10 +1244,10 @@ | |
| 1217 1244 | 
             
            								// if there is NOT a logical 'or', or range ( 'to' or '-' ) in the string
         | 
| 1218 1245 | 
             
            								!regex.alreadyFiltered.test( val ) &&
         | 
| 1219 1246 | 
             
            								// if we are not doing exact matches, using '|' ( logical or ) or not '!'
         | 
| 1220 | 
            -
            								 | 
| 1247 | 
            +
            								!regex.exactTest.test( val ) &&
         | 
| 1221 1248 | 
             
            								// don't search only filtered if the value is negative
         | 
| 1222 1249 | 
             
            								// ( '> -10' => '> -100' will ignore hidden rows )
         | 
| 1223 | 
            -
            								!(  | 
| 1250 | 
            +
            								!( regex.isNeg1.test( val ) || regex.isNeg2.test( val ) ) &&
         | 
| 1224 1251 | 
             
            								// if filtering using a select without a 'filter-match' class ( exact match ) - fixes #593
         | 
| 1225 1252 | 
             
            								!( val !== '' && c.$filters && c.$filters.eq( indx ).find( 'select' ).length &&
         | 
| 1226 1253 | 
             
            									!c.$headerIndexed[indx].hasClass( 'filter-match' ) );
         | 
| @@ -1239,7 +1266,7 @@ | |
| 1239 1266 | 
             
            							data.anyMatchFilter = ts.replaceAccents( data.anyMatchFilter );
         | 
| 1240 1267 | 
             
            						}
         | 
| 1241 1268 | 
             
            						if ( wo.filter_defaultFilter && regex.iQuery.test( vars.defaultAnyFilter ) ) {
         | 
| 1242 | 
            -
            							data.anyMatchFilter =  | 
| 1269 | 
            +
            							data.anyMatchFilter = tsf.defaultFilter( data.anyMatchFilter, vars.defaultAnyFilter );
         | 
| 1243 1270 | 
             
            							// clear search filtered flag because default filters are not saved to the last search
         | 
| 1244 1271 | 
             
            							searchFiltered = false;
         | 
| 1245 1272 | 
             
            						}
         | 
| @@ -1282,7 +1309,7 @@ | |
| 1282 1309 | 
             
            								'';
         | 
| 1283 1310 | 
             
            						}
         | 
| 1284 1311 |  | 
| 1285 | 
            -
            						showRow =  | 
| 1312 | 
            +
            						showRow = tsf.processRow( c, data, vars );
         | 
| 1286 1313 | 
             
            						childRow = rowData.$row.filter( ':gt( 0 )' );
         | 
| 1287 1314 |  | 
| 1288 1315 | 
             
            						if ( wo.filter_childRows && childRow.length ) {
         | 
| @@ -1293,7 +1320,7 @@ | |
| 1293 1320 | 
             
            									data.cacheArray = rowData.child[ indx ];
         | 
| 1294 1321 | 
             
            									data.rawArray = data.cacheArray;
         | 
| 1295 1322 | 
             
            									// use OR comparison on child rows
         | 
| 1296 | 
            -
            									showRow = showRow ||  | 
| 1323 | 
            +
            									showRow = showRow || tsf.processRow( c, data, vars );
         | 
| 1297 1324 | 
             
            								}
         | 
| 1298 1325 | 
             
            							}
         | 
| 1299 1326 | 
             
            							childRow.toggleClass( wo.filter_filteredRow, !showRow );
         | 
| @@ -1355,7 +1382,7 @@ | |
| 1355 1382 | 
             
            			}
         | 
| 1356 1383 | 
             
            			if ( arry === false ) {
         | 
| 1357 1384 | 
             
            				// fall back to original method
         | 
| 1358 | 
            -
            				arry =  | 
| 1385 | 
            +
            				arry = tsf.getOptions( table, column, onlyAvail );
         | 
| 1359 1386 | 
             
            			}
         | 
| 1360 1387 |  | 
| 1361 1388 | 
             
            			// get unique elements and sort the list
         | 
| @@ -1467,13 +1494,13 @@ | |
| 1467 1494 | 
             
            			// nothing included in arry ( external source ), so get the options from
         | 
| 1468 1495 | 
             
            			// filter_selectSource or column data
         | 
| 1469 1496 | 
             
            			if ( typeof arry === 'undefined' || arry === '' ) {
         | 
| 1470 | 
            -
            				arry =  | 
| 1497 | 
            +
            				arry = tsf.getOptionSource( table, column, onlyAvail );
         | 
| 1471 1498 | 
             
            			}
         | 
| 1472 1499 |  | 
| 1473 1500 | 
             
            			if ( $.isArray( arry ) ) {
         | 
| 1474 1501 | 
             
            				// build option list
         | 
| 1475 1502 | 
             
            				for ( indx = 0; indx < arry.length; indx++ ) {
         | 
| 1476 | 
            -
            					txt = arry[indx] = ( '' + arry[indx] ).replace(  | 
| 1503 | 
            +
            					txt = arry[indx] = ( '' + arry[indx] ).replace( tsf.regex.quote, '"' );
         | 
| 1477 1504 | 
             
            					val = txt;
         | 
| 1478 1505 | 
             
            					// allow including a symbol in the selectSource array
         | 
| 1479 1506 | 
             
            					// 'a-z|A through Z' so that 'a-z' becomes the option value
         | 
| @@ -1529,7 +1556,7 @@ | |
| 1529 1556 | 
             
            				// look for the filter-select class; build/update it if found
         | 
| 1530 1557 | 
             
            				if ( ( $header.hasClass( 'filter-select' ) ||
         | 
| 1531 1558 | 
             
            					ts.getColumnData( table, wo.filter_functions, columnIndex ) === true ) && noSelect ) {
         | 
| 1532 | 
            -
            					 | 
| 1559 | 
            +
            					tsf.buildSelect( table, columnIndex, '', updating, $header.hasClass( wo.filter_onlyAvail ) );
         | 
| 1533 1560 | 
             
            				}
         | 
| 1534 1561 | 
             
            			}
         | 
| 1535 1562 | 
             
            		}
         | 
| @@ -1565,7 +1592,7 @@ | |
| 1565 1592 | 
             
            					$column = $filters.filter( cols );
         | 
| 1566 1593 | 
             
            					if ( $column.length ) {
         | 
| 1567 1594 | 
             
            						// move the latest search to the first slot in the array
         | 
| 1568 | 
            -
            						$column =  | 
| 1595 | 
            +
            						$column = tsf.getLatestSearch( $column );
         | 
| 1569 1596 | 
             
            						if ( $.isArray( setFilters ) ) {
         | 
| 1570 1597 | 
             
            							// skip first ( latest input ) to maintain cursor position while typing
         | 
| 1571 1598 | 
             
            							if ( skipFirst && $column.length > 1 ) {
         | 
| @@ -1615,7 +1642,7 @@ | |
| 1615 1642 | 
             
            			// ensure new set filters are applied, even if the search is the same
         | 
| 1616 1643 | 
             
            			c.lastCombinedFilter = null;
         | 
| 1617 1644 | 
             
            			c.lastSearch = [];
         | 
| 1618 | 
            -
            			 | 
| 1645 | 
            +
            			tsf.searching( c.table, filter, skipFirst );
         | 
| 1619 1646 | 
             
            			c.$table.trigger( 'filterFomatterUpdate' );
         | 
| 1620 1647 | 
             
            		}
         | 
| 1621 1648 | 
             
            		return !!valid;
         |