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