|
1 /* |
|
2 * File: jquery.dataTables.columnFilter.js |
|
3 * Version: 1.5.3. |
|
4 * Author: Jovan Popovic |
|
5 * |
|
6 * Copyright 2011-2014 Jovan Popovic, all rights reserved. |
|
7 * |
|
8 * This source file is free software, under either the GPL v2 license or a |
|
9 * BSD style license, as supplied with this software. |
|
10 * |
|
11 * This source file is distributed in the hope that it will be useful, but |
|
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
|
13 * or FITNESS FOR A PARTICULAR PURPOSE. |
|
14 * |
|
15 * Parameters:" |
|
16 * @sPlaceHolder String Place where inline filtering function should be placed ("tfoot", "thead:before", "thead:after"). Default is "tfoot" |
|
17 * @sRangeSeparator String Separator that will be used when range values are sent to the server-side. Default value is "~". |
|
18 * @sRangeFormat string Default format of the From ... to ... range inputs. Default is From {from} to {to} |
|
19 * @aoColumns Array Array of the filter settings that will be applied on the columns |
|
20 */ |
|
21 (function ($) { |
|
22 |
|
23 |
|
24 $.fn.columnFilter = function (options) { |
|
25 |
|
26 var asInitVals, i, label, th; |
|
27 |
|
28 //var sTableId = "table"; |
|
29 var sRangeFormat = "From {from} to {to}"; |
|
30 //Array of the functions that will override sSearch_ parameters |
|
31 var afnSearch_ = new Array(); |
|
32 var aiCustomSearch_Indexes = new Array(); |
|
33 |
|
34 var oFunctionTimeout = null; |
|
35 |
|
36 var fnOnFiltered = function () { |
|
37 }; |
|
38 |
|
39 function _fnGetColumnValues(oSettings, iColumn, bUnique, bFiltered, bIgnoreEmpty) { |
|
40 ///<summary> |
|
41 ///Return values in the column |
|
42 ///</summary> |
|
43 ///<param name="oSettings" type="Object">DataTables settings</param> |
|
44 ///<param name="iColumn" type="int">Id of the column</param> |
|
45 ///<param name="bUnique" type="bool">Return only distinct values</param> |
|
46 ///<param name="bFiltered" type="bool">Return values only from the filtered rows</param> |
|
47 ///<param name="bIgnoreEmpty" type="bool">Ignore empty cells</param> |
|
48 |
|
49 // check that we have a column id |
|
50 if (typeof iColumn == "undefined") return new Array(); |
|
51 |
|
52 // by default we only wany unique data |
|
53 if (typeof bUnique == "undefined") bUnique = true; |
|
54 |
|
55 // by default we do want to only look at filtered data |
|
56 if (typeof bFiltered == "undefined") bFiltered = true; |
|
57 |
|
58 // by default we do not wany to include empty values |
|
59 if (typeof bIgnoreEmpty == "undefined") bIgnoreEmpty = true; |
|
60 |
|
61 // list of rows which we're going to loop through |
|
62 var aiRows; |
|
63 |
|
64 // use only filtered rows |
|
65 if (bFiltered == true) aiRows = oSettings.aiDisplay; |
|
66 // use all rows |
|
67 else aiRows = oSettings.aiDisplayMaster; // all row numbers |
|
68 |
|
69 // set up data array |
|
70 var asResultData = new Array(); |
|
71 |
|
72 for (var i = 0, c = aiRows.length; i < c; i++) { |
|
73 var iRow = aiRows[i]; |
|
74 var aData = oTable.fnGetData(iRow); |
|
75 var sValue = aData[iColumn]; |
|
76 |
|
77 // ignore empty values? |
|
78 if (bIgnoreEmpty == true && sValue.length == 0) continue; |
|
79 |
|
80 // ignore unique values? |
|
81 else if (bUnique == true && jQuery.inArray(sValue, asResultData) > -1) continue; |
|
82 |
|
83 // else push the value onto the result data array |
|
84 else asResultData.push(sValue); |
|
85 } |
|
86 |
|
87 return asResultData.sort(); |
|
88 } |
|
89 |
|
90 function _fnColumnIndex(iColumnIndex) { |
|
91 if (properties.bUseColVis) |
|
92 return iColumnIndex; |
|
93 else |
|
94 return oTable.fnSettings().oApi._fnVisibleToColumnIndex(oTable.fnSettings(), iColumnIndex); |
|
95 //return iColumnIndex; |
|
96 //return oTable.fnSettings().oApi._fnColumnIndexToVisible(oTable.fnSettings(), iColumnIndex); |
|
97 } |
|
98 |
|
99 function fnCreateInput(oTable, regex, smart, bIsNumber, iFilterLength, iMaxLenght) { |
|
100 var sCSSClass = "text_filter"; |
|
101 if (bIsNumber) |
|
102 sCSSClass = "number_filter"; |
|
103 |
|
104 label = label.replace(/(^\s*)|(\s*$)/g, ""); |
|
105 var currentFilter = oTable.fnSettings().aoPreSearchCols[i].sSearch; |
|
106 var search_init = 'search_init '; |
|
107 var inputvalue = label; |
|
108 if (currentFilter != '' && currentFilter != '^') { |
|
109 if (bIsNumber && currentFilter.charAt(0) == '^') |
|
110 inputvalue = currentFilter.substr(1); //ignore trailing ^ |
|
111 else |
|
112 inputvalue = currentFilter; |
|
113 search_init = ''; |
|
114 } |
|
115 |
|
116 var input = $('<input type="text" class="' + search_init + sCSSClass + '" value="' + inputvalue + '" rel="' + i + '"/>'); |
|
117 if (iMaxLenght != undefined && iMaxLenght != -1) { |
|
118 input.attr('maxlength', iMaxLenght); |
|
119 } |
|
120 th.html(input); |
|
121 if (bIsNumber) |
|
122 th.wrapInner('<span class="filter_column filter_number" />'); |
|
123 else |
|
124 th.wrapInner('<span class="filter_column filter_text" />'); |
|
125 |
|
126 asInitVals[i] = label; |
|
127 var index = i; |
|
128 |
|
129 if (bIsNumber && !oTable.fnSettings().oFeatures.bServerSide) { |
|
130 input.keyup(function () { |
|
131 /* Filter on the column all numbers that starts with the entered value */ |
|
132 oTable.fnFilter('^' + this.value, _fnColumnIndex(index), true, false); //Issue 37 |
|
133 fnOnFiltered(); |
|
134 }); |
|
135 } else { |
|
136 input.keyup(function () { |
|
137 if (oTable.fnSettings().oFeatures.bServerSide && iFilterLength != 0) { |
|
138 //If filter length is set in the server-side processing mode |
|
139 //Check has the user entered at least iFilterLength new characters |
|
140 |
|
141 var currentFilter = oTable.fnSettings().aoPreSearchCols[index].sSearch; |
|
142 var iLastFilterLength = $(this).data("dt-iLastFilterLength"); |
|
143 if (typeof iLastFilterLength == "undefined") |
|
144 iLastFilterLength = 0; |
|
145 var iCurrentFilterLength = this.value.length; |
|
146 if (Math.abs(iCurrentFilterLength - iLastFilterLength) < iFilterLength |
|
147 //&& currentFilter.length == 0 //Why this? |
|
148 ) { |
|
149 //Cancel the filtering |
|
150 return; |
|
151 } |
|
152 else { |
|
153 //Remember the current filter length |
|
154 $(this).data("dt-iLastFilterLength", iCurrentFilterLength); |
|
155 } |
|
156 } |
|
157 /* Filter on the column (the index) of this element */ |
|
158 oTable.fnFilter(this.value, _fnColumnIndex(index), regex, smart); //Issue 37 |
|
159 fnOnFiltered(); |
|
160 }); |
|
161 } |
|
162 |
|
163 input.focus(function () { |
|
164 if ($(this).hasClass("search_init")) { |
|
165 $(this).removeClass("search_init"); |
|
166 this.value = ""; |
|
167 } |
|
168 }); |
|
169 input.blur(function () { |
|
170 if (this.value == "") { |
|
171 $(this).addClass("search_init"); |
|
172 this.value = asInitVals[index]; |
|
173 } |
|
174 }); |
|
175 } |
|
176 |
|
177 function fnCreateRangeInput(oTable) { |
|
178 |
|
179 //var currentFilter = oTable.fnSettings().aoPreSearchCols[i].sSearch; |
|
180 th.html(_fnRangeLabelPart(0)); |
|
181 var sFromId = oTable.attr("id") + '_range_from_' + i; |
|
182 var from = $('<input type="text" class="number_range_filter" id="' + sFromId + '" rel="' + i + '"/>'); |
|
183 th.append(from); |
|
184 th.append(_fnRangeLabelPart(1)); |
|
185 var sToId = oTable.attr("id") + '_range_to_' + i; |
|
186 var to = $('<input type="text" class="number_range_filter" id="' + sToId + '" rel="' + i + '"/>'); |
|
187 th.append(to); |
|
188 th.append(_fnRangeLabelPart(2)); |
|
189 th.wrapInner('<span class="filter_column filter_number_range" />'); |
|
190 var index = i; |
|
191 aiCustomSearch_Indexes.push(i); |
|
192 |
|
193 |
|
194 //------------start range filtering function |
|
195 |
|
196 |
|
197 /* Custom filtering function which will filter data in column four between two values |
|
198 * Author: Allan Jardine, Modified by Jovan Popovic |
|
199 */ |
|
200 //$.fn.dataTableExt.afnFiltering.push( |
|
201 oTable.dataTableExt.afnFiltering.push( |
|
202 function (oSettings, aData, iDataIndex) { |
|
203 if (oTable.attr("id") != oSettings.sTableId) |
|
204 return true; |
|
205 // Try to handle missing nodes more gracefully |
|
206 if (document.getElementById(sFromId) == null) |
|
207 return true; |
|
208 var iMin = document.getElementById(sFromId).value * 1; |
|
209 var iMax = document.getElementById(sToId).value * 1; |
|
210 var iValue = aData[_fnColumnIndex(index)] == "-" ? 0 : aData[_fnColumnIndex(index)] * 1; |
|
211 if (iMin == "" && iMax == "") { |
|
212 return true; |
|
213 } |
|
214 else if (iMin == "" && iValue <= iMax) { |
|
215 return true; |
|
216 } |
|
217 else if (iMin <= iValue && "" == iMax) { |
|
218 return true; |
|
219 } |
|
220 else if (iMin <= iValue && iValue <= iMax) { |
|
221 return true; |
|
222 } |
|
223 return false; |
|
224 } |
|
225 ); |
|
226 //------------end range filtering function |
|
227 |
|
228 |
|
229 $('#' + sFromId + ',#' + sToId, th).keyup(function () { |
|
230 |
|
231 var iMin = document.getElementById(sFromId).value * 1; |
|
232 var iMax = document.getElementById(sToId).value * 1; |
|
233 if (iMin != 0 && iMax != 0 && iMin > iMax) |
|
234 return; |
|
235 |
|
236 oTable.fnDraw(); |
|
237 fnOnFiltered(); |
|
238 }); |
|
239 |
|
240 |
|
241 } |
|
242 |
|
243 |
|
244 function fnCreateDateRangeInput(oTable) { |
|
245 |
|
246 var aoFragments = sRangeFormat.split(/[}{]/); |
|
247 |
|
248 th.html(""); |
|
249 //th.html(_fnRangeLabelPart(0)); |
|
250 var sFromId = oTable.attr("id") + '_range_from_' + i; |
|
251 var from = $('<input type="text" class="date_range_filter" id="' + sFromId + '" rel="' + i + '"/>'); |
|
252 from.datepicker(); |
|
253 //th.append(from); |
|
254 //th.append(_fnRangeLabelPart(1)); |
|
255 var sToId = oTable.attr("id") + '_range_to_' + i; |
|
256 var to = $('<input type="text" class="date_range_filter" id="' + sToId + '" rel="' + i + '"/>'); |
|
257 //th.append(to); |
|
258 //th.append(_fnRangeLabelPart(2)); |
|
259 |
|
260 for (ti = 0; ti < aoFragments.length; ti++) { |
|
261 |
|
262 if (aoFragments[ti] == properties.sDateFromToken) { |
|
263 th.append(from); |
|
264 } else { |
|
265 if (aoFragments[ti] == properties.sDateToToken) { |
|
266 th.append(to); |
|
267 } else { |
|
268 th.append(aoFragments[ti]); |
|
269 } |
|
270 } |
|
271 |
|
272 |
|
273 } |
|
274 |
|
275 |
|
276 th.wrapInner('<span class="filter_column filter_date_range" />'); |
|
277 to.datepicker(); |
|
278 var index = i; |
|
279 aiCustomSearch_Indexes.push(i); |
|
280 |
|
281 |
|
282 //------------start date range filtering function |
|
283 |
|
284 //$.fn.dataTableExt.afnFiltering.push( |
|
285 oTable.dataTableExt.afnFiltering.push( |
|
286 function (oSettings, aData, iDataIndex) { |
|
287 if (oTable.attr("id") != oSettings.sTableId) |
|
288 return true; |
|
289 |
|
290 var dStartDate = from.datepicker("getDate"); |
|
291 |
|
292 var dEndDate = to.datepicker("getDate"); |
|
293 |
|
294 if (dStartDate == null && dEndDate == null) { |
|
295 return true; |
|
296 } |
|
297 |
|
298 var dCellDate = null; |
|
299 try { |
|
300 if (aData[_fnColumnIndex(index)] == null || aData[_fnColumnIndex(index)] == "") |
|
301 return false; |
|
302 dCellDate = $.datepicker.parseDate($.datepicker.regional[""].dateFormat, aData[_fnColumnIndex(index)]); |
|
303 } catch (ex) { |
|
304 return false; |
|
305 } |
|
306 if (dCellDate == null) |
|
307 return false; |
|
308 |
|
309 |
|
310 if (dStartDate == null && dCellDate <= dEndDate) { |
|
311 return true; |
|
312 } |
|
313 else if (dStartDate <= dCellDate && dEndDate == null) { |
|
314 return true; |
|
315 } |
|
316 else if (dStartDate <= dCellDate && dCellDate <= dEndDate) { |
|
317 return true; |
|
318 } |
|
319 return false; |
|
320 } |
|
321 ); |
|
322 //------------end date range filtering function |
|
323 |
|
324 $('#' + sFromId + ',#' + sToId, th).change(function () { |
|
325 oTable.fnDraw(); |
|
326 fnOnFiltered(); |
|
327 }); |
|
328 |
|
329 |
|
330 } |
|
331 |
|
332 function fnCreateColumnSelect(oTable, aData, iColumn, nTh, sLabel, bRegex, oSelected) { |
|
333 if (aData == null) |
|
334 aData = _fnGetColumnValues(oTable.fnSettings(), iColumn, true, false, true); |
|
335 var index = iColumn; |
|
336 var currentFilter = oTable.fnSettings().aoPreSearchCols[i].sSearch; |
|
337 if (currentFilter == null || currentFilter == "")//Issue 81 |
|
338 currentFilter = oSelected; |
|
339 |
|
340 var r = '<select class="search_init select_filter" rel="' + i + '"><option value="" class="search_init">' + sLabel + '</option>'; |
|
341 var j = 0; |
|
342 var iLen = aData.length; |
|
343 for (j = 0; j < iLen; j++) { |
|
344 if (typeof (aData[j]) != 'object') { |
|
345 var selected = ''; |
|
346 if (escape(aData[j]) == currentFilter |
|
347 || escape(aData[j]) == escape(currentFilter) |
|
348 ) |
|
349 selected = 'selected ' |
|
350 r += '<option ' + selected + ' value="' + escape(aData[j]) + '">' + aData[j] + '</option>'; |
|
351 } |
|
352 else { |
|
353 var selected = ''; |
|
354 if (bRegex) { |
|
355 //Do not escape values if they are explicitely set to avoid escaping special characters in the regexp |
|
356 if (aData[j].value == currentFilter) selected = 'selected '; |
|
357 r += '<option ' + selected + 'value="' + aData[j].value + '">' + aData[j].label + '</option>'; |
|
358 } else { |
|
359 if (escape(aData[j].value) == currentFilter) selected = 'selected '; |
|
360 r += '<option ' + selected + 'value="' + escape(aData[j].value) + '">' + aData[j].label + '</option>'; |
|
361 } |
|
362 } |
|
363 } |
|
364 |
|
365 var select = $(r + '</select>'); |
|
366 nTh.html(select); |
|
367 nTh.wrapInner('<span class="filter_column filter_select" />'); |
|
368 select.change(function () { |
|
369 //var val = $(this).val(); |
|
370 if ($(this).val() != "") { |
|
371 $(this).removeClass("search_init"); |
|
372 } else { |
|
373 $(this).addClass("search_init"); |
|
374 } |
|
375 if (bRegex) |
|
376 oTable.fnFilter($(this).val(), iColumn, bRegex); //Issue 41 |
|
377 else |
|
378 oTable.fnFilter(unescape($(this).val()), iColumn); //Issue 25 |
|
379 fnOnFiltered(); |
|
380 }); |
|
381 if (currentFilter != null && currentFilter != "")//Issue 81 |
|
382 oTable.fnFilter(unescape(currentFilter), iColumn); |
|
383 } |
|
384 |
|
385 function fnCreateSelect(oTable, aData, bRegex, oSelected) { |
|
386 var oSettings = oTable.fnSettings(); |
|
387 if (aData == null && oSettings.sAjaxSource != "" && !oSettings.oFeatures.bServerSide) { |
|
388 // Add a function to the draw callback, which will check for the Ajax data having |
|
389 // been loaded. Use a closure for the individual column elements that are used to |
|
390 // built the column filter, since 'i' and 'th' (etc) are locally "global". |
|
391 oSettings.aoDrawCallback.push({ |
|
392 "fn": (function (iColumn, nTh, sLabel) { |
|
393 return function () { |
|
394 // Only rebuild the select on the second draw - i.e. when the Ajax |
|
395 // data has been loaded. |
|
396 if (oSettings.iDraw == 2 && oSettings.sAjaxSource != null && oSettings.sAjaxSource != "" && !oSettings.oFeatures.bServerSide) { |
|
397 return fnCreateColumnSelect(oTable, null, _fnColumnIndex(iColumn), nTh, sLabel, bRegex, oSelected); //Issue 37 |
|
398 } |
|
399 }; |
|
400 })(i, th, label), |
|
401 "sName": "column_filter_" + i |
|
402 }); |
|
403 } |
|
404 // Regardless of the Ajax state, build the select on first pass |
|
405 fnCreateColumnSelect(oTable, aData, _fnColumnIndex(i), th, label, bRegex, oSelected); //Issue 37 |
|
406 |
|
407 } |
|
408 |
|
409 function fnCreateDropdown(aData) { |
|
410 var index = i; |
|
411 var r = '<div class="dropdown select_filter"><a class="dropdown-toggle" data-toggle="dropdown" href="#">' + label + '<b class="caret"></b></a><ul class="dropdown-menu" role="menu"><li data-value=""><a>Show All</a></li>', j, iLen = aData.length; |
|
412 |
|
413 for (j = 0; j < iLen; j++) { |
|
414 r += '<li data-value="' + aData[j] + '"><a>' + aData[j] + '</a></li>'; |
|
415 } |
|
416 var select = $(r + '</ul></div>'); |
|
417 th.html(select); |
|
418 th.wrapInner('<span class="filterColumn filter_select" />'); |
|
419 select.find('li').click(function () { |
|
420 oTable.fnFilter($(this).data('value'), index); |
|
421 }); |
|
422 } |
|
423 |
|
424 |
|
425 function fnCreateCheckbox(oTable, aData) { |
|
426 |
|
427 if (aData == null) |
|
428 aData = _fnGetColumnValues(oTable.fnSettings(), i, true, true, true); |
|
429 var index = i; |
|
430 |
|
431 var r = '', j, iLen = aData.length; |
|
432 |
|
433 //clean the string |
|
434 var localLabel = label.replace('%', 'Perc').replace("&", "AND").replace("$", "DOL").replace("£", "STERL").replace("@", "AT").replace(/\s/g, "_"); |
|
435 localLabel = localLabel.replace(/[^a-zA-Z 0-9]+/g, ''); |
|
436 //clean the string |
|
437 |
|
438 //button label override |
|
439 var labelBtn = label; |
|
440 if (properties.sFilterButtonText != null || properties.sFilterButtonText != undefined) { |
|
441 labelBtn = properties.sFilterButtonText; |
|
442 } |
|
443 |
|
444 var relativeDivWidthToggleSize = 10; |
|
445 var numRow = 12; //numero di checkbox per colonna |
|
446 var numCol = Math.floor(iLen / numRow); |
|
447 if (iLen % numRow > 0) { |
|
448 numCol = numCol + 1; |
|
449 } |
|
450 ; |
|
451 |
|
452 //count how many column should be generated and split the div size |
|
453 var divWidth = 100 / numCol - 2; |
|
454 |
|
455 var divWidthToggle = relativeDivWidthToggleSize * numCol; |
|
456 |
|
457 if (numCol == 1) { |
|
458 divWidth = 20; |
|
459 } |
|
460 |
|
461 var divRowDef = '<div style="float:left; min-width: ' + divWidth + '%; " >'; |
|
462 var divClose = '</div>'; |
|
463 |
|
464 var uniqueId = oTable.attr("id") + localLabel; |
|
465 var buttonId = "chkBtnOpen" + uniqueId; |
|
466 var checkToggleDiv = uniqueId + "-flt-toggle"; |
|
467 r += '<button id="' + buttonId + '" class="checkbox_filter" > ' + labelBtn + '</button>'; //filter button witch open dialog |
|
468 r += '<div id="' + checkToggleDiv + '" ' |
|
469 + 'title="' + label + '" ' |
|
470 + 'rel="' + i + '" ' |
|
471 + 'class="toggle-check ui-widget-content ui-corner-all" style="width: ' + (divWidthToggle) + '%; " >'; //dialog div |
|
472 //r+= '<div align="center" style="margin-top: 5px; "> <button id="'+buttonId+'Reset" class="checkbox_filter" > reset </button> </div>'; //reset button and its div |
|
473 r += divRowDef; |
|
474 |
|
475 for (j = 0; j < iLen; j++) { |
|
476 |
|
477 //if last check close div |
|
478 if (j % numRow == 0 && j != 0) { |
|
479 r += divClose + divRowDef; |
|
480 } |
|
481 |
|
482 var sLabel = aData[j]; |
|
483 var sValue = aData[j]; |
|
484 |
|
485 if (typeof (aData[j]) == 'object') { |
|
486 sLabel = aData[j].label; |
|
487 sValue = aData[j].value; |
|
488 } |
|
489 |
|
490 //check button |
|
491 r += '<input class="search_init checkbox_filter" type="checkbox" id= "' + uniqueId + '_cb_' + sValue + '" name= "' + localLabel + '" value="' + sValue + '" >' + sLabel + '<br/>'; |
|
492 |
|
493 var checkbox = $(r); |
|
494 th.html(checkbox); |
|
495 th.wrapInner('<span class="filter_column filter_checkbox" />'); |
|
496 //on every checkbox selection |
|
497 checkbox.change(function () { |
|
498 |
|
499 var search = ''; |
|
500 var or = '|'; //var for select checks in 'or' into the regex |
|
501 var resSize = $('input:checkbox[name="' + localLabel + '"]:checked').size(); |
|
502 $('input:checkbox[name="' + localLabel + '"]:checked').each(function (index) { |
|
503 |
|
504 //search = search + ' ' + $(this).val(); |
|
505 //concatenation for selected checks in or |
|
506 if ((index == 0 && resSize == 1) |
|
507 || (index != 0 && index == resSize - 1)) { |
|
508 or = ''; |
|
509 } |
|
510 //trim |
|
511 search = search.replace(/^\s+|\s+$/g, ""); |
|
512 search = search + $(this).val() + or; |
|
513 or = '|'; |
|
514 |
|
515 }); |
|
516 |
|
517 |
|
518 if (search != "") { |
|
519 $('input:checkbox[name="' + localLabel + '"]').removeClass("search_init"); |
|
520 } else { |
|
521 $('input:checkbox[name="' + localLabel + '"]').addClass("search_init"); |
|
522 } |
|
523 /* Old code for setting search_init CSS class on checkboxes if any of them is checked |
|
524 for (var jj = 0; jj < iLen; jj++) { |
|
525 if (search != "") { |
|
526 $('#' + aData[jj]).removeClass("search_init"); |
|
527 } else { |
|
528 $('#' + aData[jj]).addClass("search_init"); |
|
529 } |
|
530 } |
|
531 */ |
|
532 |
|
533 //execute search |
|
534 oTable.fnFilter(search, index, true, false); |
|
535 fnOnFiltered(); |
|
536 }); |
|
537 } |
|
538 |
|
539 //filter button |
|
540 $('#' + buttonId).button(); |
|
541 //dialog |
|
542 $('#' + checkToggleDiv).dialog({ |
|
543 //height: 140, |
|
544 autoOpen: false, |
|
545 //show: "blind", |
|
546 hide: "blind", |
|
547 buttons: [ |
|
548 { |
|
549 text: "Reset", |
|
550 click: function () { |
|
551 //$('#'+buttonId).removeClass("filter_selected"); //LM remove border if filter selected |
|
552 $('input:checkbox[name="' + localLabel + '"]:checked').each(function (index3) { |
|
553 $(this).attr('checked', false); |
|
554 $(this).addClass("search_init"); |
|
555 }); |
|
556 oTable.fnFilter('', index, true, false); |
|
557 fnOnFiltered(); |
|
558 return false; |
|
559 } |
|
560 }, |
|
561 { |
|
562 text: "Close", |
|
563 click: function () { |
|
564 $(this).dialog("close"); |
|
565 } |
|
566 } |
|
567 ] |
|
568 }); |
|
569 |
|
570 |
|
571 $('#' + buttonId).click(function () { |
|
572 |
|
573 $('#' + checkToggleDiv).dialog('open'); |
|
574 var target = $(this); |
|
575 $('#' + checkToggleDiv).dialog("widget").position({ my: 'top', |
|
576 at: 'bottom', |
|
577 of: target |
|
578 }); |
|
579 |
|
580 return false; |
|
581 }); |
|
582 |
|
583 var fnOnFilteredCurrent = fnOnFiltered; |
|
584 |
|
585 fnOnFiltered = function () { |
|
586 var target = $('#' + buttonId); |
|
587 $('#' + checkToggleDiv).dialog("widget").position({ my: 'top', |
|
588 at: 'bottom', |
|
589 of: target |
|
590 }); |
|
591 fnOnFilteredCurrent(); |
|
592 }; |
|
593 //reset |
|
594 /* |
|
595 $('#'+buttonId+"Reset").button(); |
|
596 $('#'+buttonId+"Reset").click(function(){ |
|
597 $('#'+buttonId).removeClass("filter_selected"); //LM remove border if filter selected |
|
598 $('input:checkbox[name="'+localLabel+'"]:checked').each(function(index3) { |
|
599 $(this).attr('checked', false); |
|
600 $(this).addClass("search_init"); |
|
601 }); |
|
602 oTable.fnFilter('', index, true, false); |
|
603 return false; |
|
604 }); |
|
605 */ |
|
606 } |
|
607 |
|
608 |
|
609 function _fnRangeLabelPart(iPlace) { |
|
610 switch (iPlace) { |
|
611 case 0: |
|
612 return sRangeFormat.substring(0, sRangeFormat.indexOf("{from}")); |
|
613 case 1: |
|
614 return sRangeFormat.substring(sRangeFormat.indexOf("{from}") + 6, sRangeFormat.indexOf("{to}")); |
|
615 default: |
|
616 return sRangeFormat.substring(sRangeFormat.indexOf("{to}") + 4); |
|
617 } |
|
618 } |
|
619 |
|
620 |
|
621 var oTable = this; |
|
622 |
|
623 var defaults = { |
|
624 sPlaceHolder: "foot", |
|
625 sRangeSeparator: "~", |
|
626 iFilteringDelay: 500, |
|
627 aoColumns: null, |
|
628 sRangeFormat: "From {from} to {to}", |
|
629 sDateFromToken: "from", |
|
630 sDateToToken: "to" |
|
631 }; |
|
632 |
|
633 var properties = $.extend(defaults, options); |
|
634 |
|
635 return this.each(function () { |
|
636 |
|
637 if (!oTable.fnSettings().oFeatures.bFilter) |
|
638 return; |
|
639 asInitVals = new Array(); |
|
640 |
|
641 var aoFilterCells = oTable.fnSettings().aoFooter[0]; |
|
642 |
|
643 var oHost = oTable.fnSettings().nTFoot; //Before fix for ColVis |
|
644 var sFilterRow = "tr"; //Before fix for ColVis |
|
645 |
|
646 if (properties.sPlaceHolder == "head:after") { |
|
647 var tr = $("tr:first", oTable.fnSettings().nTHead).detach(); |
|
648 //tr.appendTo($(oTable.fnSettings().nTHead)); |
|
649 if (oTable.fnSettings().bSortCellsTop) { |
|
650 tr.prependTo($(oTable.fnSettings().nTHead)); |
|
651 //tr.appendTo($("thead", oTable)); |
|
652 aoFilterCells = oTable.fnSettings().aoHeader[1]; |
|
653 } |
|
654 else { |
|
655 tr.appendTo($(oTable.fnSettings().nTHead)); |
|
656 //tr.prependTo($("thead", oTable)); |
|
657 aoFilterCells = oTable.fnSettings().aoHeader[0]; |
|
658 } |
|
659 |
|
660 sFilterRow = "tr:last"; |
|
661 oHost = oTable.fnSettings().nTHead; |
|
662 |
|
663 } else if (properties.sPlaceHolder == "head:before") { |
|
664 |
|
665 if (oTable.fnSettings().bSortCellsTop) { |
|
666 var tr = $("tr:first", oTable.fnSettings().nTHead).detach(); |
|
667 tr.appendTo($(oTable.fnSettings().nTHead)); |
|
668 aoFilterCells = oTable.fnSettings().aoHeader[1]; |
|
669 } else { |
|
670 aoFilterCells = oTable.fnSettings().aoHeader[0]; |
|
671 } |
|
672 /*else { |
|
673 //tr.prependTo($("thead", oTable)); |
|
674 sFilterRow = "tr:first"; |
|
675 }*/ |
|
676 |
|
677 sFilterRow = "tr:first"; |
|
678 |
|
679 oHost = oTable.fnSettings().nTHead; |
|
680 |
|
681 |
|
682 } |
|
683 |
|
684 //$(sFilterRow + " th", oHost).each(function (index) {//bug with ColVis |
|
685 $(aoFilterCells).each(function (index) {//fix for ColVis |
|
686 i = index; |
|
687 var aoColumn = { type: "text", |
|
688 bRegex: false, |
|
689 bSmart: true, |
|
690 iMaxLenght: -1, |
|
691 iFilterLength: 0 |
|
692 }; |
|
693 if (properties.aoColumns != null) { |
|
694 if (properties.aoColumns.length < i || properties.aoColumns[i] == null) |
|
695 return; |
|
696 aoColumn = properties.aoColumns[i]; |
|
697 } |
|
698 //label = $(this).text(); //Before fix for ColVis |
|
699 label = $($(this)[0].cell).text(); //Fix for ColVis |
|
700 if (aoColumn.sSelector == null) { |
|
701 //th = $($(this)[0]);//Before fix for ColVis |
|
702 th = $($(this)[0].cell); //Fix for ColVis |
|
703 } |
|
704 else { |
|
705 th = $(aoColumn.sSelector); |
|
706 if (th.length == 0) |
|
707 th = $($(this)[0].cell); |
|
708 } |
|
709 |
|
710 if (aoColumn != null) { |
|
711 if (aoColumn.sRangeFormat != null) |
|
712 sRangeFormat = aoColumn.sRangeFormat; |
|
713 else |
|
714 sRangeFormat = properties.sRangeFormat; |
|
715 switch (aoColumn.type) { |
|
716 case "null": |
|
717 break; |
|
718 case "number": |
|
719 fnCreateInput(oTable, true, false, true, aoColumn.iFilterLength, aoColumn.iMaxLenght); |
|
720 break; |
|
721 case "select": |
|
722 if (aoColumn.bRegex != true) |
|
723 aoColumn.bRegex = false; |
|
724 fnCreateSelect(oTable, aoColumn.values, aoColumn.bRegex, aoColumn.selected); |
|
725 break; |
|
726 case "number-range": |
|
727 fnCreateRangeInput(oTable); |
|
728 break; |
|
729 case "date-range": |
|
730 fnCreateDateRangeInput(oTable); |
|
731 break; |
|
732 case "checkbox": |
|
733 fnCreateCheckbox(oTable, aoColumn.values); |
|
734 break; |
|
735 case "twitter-dropdown": |
|
736 case "dropdown": |
|
737 fnCreateDropdown(aoColumn.values); |
|
738 break; |
|
739 case "text": |
|
740 default: |
|
741 bRegex = (aoColumn.bRegex == null ? false : aoColumn.bRegex); |
|
742 bSmart = (aoColumn.bSmart == null ? false : aoColumn.bSmart); |
|
743 fnCreateInput(oTable, bRegex, bSmart, false, aoColumn.iFilterLength, aoColumn.iMaxLenght); |
|
744 break; |
|
745 |
|
746 } |
|
747 } |
|
748 }); |
|
749 |
|
750 for (j = 0; j < aiCustomSearch_Indexes.length; j++) { |
|
751 //var index = aiCustomSearch_Indexes[j]; |
|
752 var fnSearch_ = function () { |
|
753 var id = oTable.attr("id"); |
|
754 return $("#" + id + "_range_from_" + aiCustomSearch_Indexes[j]).val() + properties.sRangeSeparator + $("#" + id + "_range_to_" + aiCustomSearch_Indexes[j]).val() |
|
755 } |
|
756 afnSearch_.push(fnSearch_); |
|
757 } |
|
758 |
|
759 if (oTable.fnSettings().oFeatures.bServerSide) { |
|
760 |
|
761 var fnServerDataOriginal = oTable.fnSettings().fnServerData; |
|
762 |
|
763 oTable.fnSettings().fnServerData = function (sSource, aoData, fnCallback) { |
|
764 |
|
765 for (j = 0; j < aiCustomSearch_Indexes.length; j++) { |
|
766 var index = aiCustomSearch_Indexes[j]; |
|
767 |
|
768 for (k = 0; k < aoData.length; k++) { |
|
769 if (aoData[k].name == "sSearch_" + index) |
|
770 aoData[k].value = afnSearch_[j](); |
|
771 } |
|
772 } |
|
773 aoData.push({ "name": "sRangeSeparator", "value": properties.sRangeSeparator }); |
|
774 |
|
775 if (fnServerDataOriginal != null) { |
|
776 try { |
|
777 fnServerDataOriginal(sSource, aoData, fnCallback, oTable.fnSettings()); //TODO: See Issue 18 |
|
778 } catch (ex) { |
|
779 fnServerDataOriginal(sSource, aoData, fnCallback); |
|
780 } |
|
781 } |
|
782 else { |
|
783 $.getJSON(sSource, aoData, function (json) { |
|
784 fnCallback(json) |
|
785 }); |
|
786 } |
|
787 }; |
|
788 |
|
789 } |
|
790 |
|
791 }); |
|
792 |
|
793 }; |
|
794 |
|
795 |
|
796 })(jQuery); |