bootstrap-table-filter-control.js 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773
  1. (function (global, factory) {
  2. if (typeof define === "function" && define.amd) {
  3. define([], factory);
  4. } else if (typeof exports !== "undefined") {
  5. factory();
  6. } else {
  7. var mod = {
  8. exports: {}
  9. };
  10. factory();
  11. global.bootstrapTableFilterControl = mod.exports;
  12. }
  13. })(this, function () {
  14. "use strict";
  15. /**
  16. * @author: Dennis Hernández
  17. * @webSite: http://djhvscf.github.io/Blog
  18. * @version: v2.1.2
  19. */
  20. (function ($) {
  21. 'use strict';
  22. var sprintf = $.fn.bootstrapTable.utils.sprintf,
  23. objectKeys = $.fn.bootstrapTable.utils.objectKeys;
  24. var getOptionsFromSelectControl = function getOptionsFromSelectControl(selectControl) {
  25. return selectControl.get(selectControl.length - 1).options;
  26. };
  27. var hideUnusedSelectOptions = function hideUnusedSelectOptions(selectControl, uniqueValues) {
  28. var options = getOptionsFromSelectControl(selectControl);
  29. for (var i = 0; i < options.length; i++) {
  30. if (options[i].value !== "") {
  31. if (!uniqueValues.hasOwnProperty(options[i].value)) {
  32. selectControl.find(sprintf("option[value='%s']", options[i].value)).hide();
  33. } else {
  34. selectControl.find(sprintf("option[value='%s']", options[i].value)).show();
  35. }
  36. }
  37. }
  38. };
  39. var addOptionToSelectControl = function addOptionToSelectControl(selectControl, value, text) {
  40. value = $.trim(value);
  41. selectControl = $(selectControl.get(selectControl.length - 1));
  42. if (!existOptionInSelectControl(selectControl, value)) {
  43. selectControl.append($("<option></option>").attr("value", value).text($('<div />').html(text).text()));
  44. }
  45. };
  46. var sortSelectControl = function sortSelectControl(selectControl) {
  47. selectControl = $(selectControl.get(selectControl.length - 1));
  48. var $opts = selectControl.find('option:gt(0)');
  49. $opts.sort(function (a, b) {
  50. a = $(a).text().toLowerCase();
  51. b = $(b).text().toLowerCase();
  52. if ($.isNumeric(a) && $.isNumeric(b)) {
  53. // Convert numerical values from string to float.
  54. a = parseFloat(a);
  55. b = parseFloat(b);
  56. }
  57. return a > b ? 1 : a < b ? -1 : 0;
  58. });
  59. selectControl.find('option:gt(0)').remove();
  60. selectControl.append($opts);
  61. };
  62. var existOptionInSelectControl = function existOptionInSelectControl(selectControl, value) {
  63. var options = getOptionsFromSelectControl(selectControl);
  64. for (var i = 0; i < options.length; i++) {
  65. if (options[i].value === value.toString()) {
  66. //The value is not valid to add
  67. return true;
  68. }
  69. }
  70. //If we get here, the value is valid to add
  71. return false;
  72. };
  73. var fixHeaderCSS = function fixHeaderCSS(that) {
  74. that.$tableHeader.css('height', '77px');
  75. };
  76. var getCurrentHeader = function getCurrentHeader(that) {
  77. var header = that.$header;
  78. if (that.options.height) {
  79. header = that.$tableHeader;
  80. }
  81. return header;
  82. };
  83. var getCurrentSearchControls = function getCurrentSearchControls(that) {
  84. var searchControls = 'select, input';
  85. if (that.options.height) {
  86. searchControls = 'table select, table input';
  87. }
  88. return searchControls;
  89. };
  90. var getCursorPosition = function getCursorPosition(el) {
  91. if ($.fn.bootstrapTable.utils.isIEBrowser()) {
  92. if ($(el).is('input[type=text]')) {
  93. var pos = 0;
  94. if ('selectionStart' in el) {
  95. pos = el.selectionStart;
  96. } else if ('selection' in document) {
  97. el.focus();
  98. var Sel = document.selection.createRange();
  99. var SelLength = document.selection.createRange().text.length;
  100. Sel.moveStart('character', -el.value.length);
  101. pos = Sel.text.length - SelLength;
  102. }
  103. return pos;
  104. } else {
  105. return -1;
  106. }
  107. } else {
  108. return -1;
  109. }
  110. };
  111. var setCursorPosition = function setCursorPosition(el) {
  112. $(el).val(el.value);
  113. };
  114. var copyValues = function copyValues(that) {
  115. var header = getCurrentHeader(that),
  116. searchControls = getCurrentSearchControls(that);
  117. that.options.valuesFilterControl = [];
  118. header.find(searchControls).each(function () {
  119. that.options.valuesFilterControl.push({
  120. field: $(this).closest('[data-field]').data('field'),
  121. value: $(this).val(),
  122. position: getCursorPosition($(this).get(0)),
  123. hasFocus: $(this).is(":focus")
  124. });
  125. });
  126. };
  127. var setValues = function setValues(that) {
  128. var field = null,
  129. result = [],
  130. header = getCurrentHeader(that),
  131. searchControls = getCurrentSearchControls(that);
  132. if (that.options.valuesFilterControl.length > 0) {
  133. // Callback to apply after settings fields values
  134. var fieldToFocusCallback = null;
  135. header.find(searchControls).each(function (index, ele) {
  136. field = $(this).closest('[data-field]').data('field');
  137. result = $.grep(that.options.valuesFilterControl, function (valueObj) {
  138. return valueObj.field === field;
  139. });
  140. if (result.length > 0) {
  141. $(this).val(result[0].value);
  142. if (result[0].hasFocus) {
  143. // set callback if the field had the focus.
  144. fieldToFocusCallback = function (fieldToFocus, carretPosition) {
  145. // Closure here to capture the field and cursor position
  146. var closedCallback = function closedCallback() {
  147. fieldToFocus.focus();
  148. setCursorPosition(fieldToFocus, carretPosition);
  149. };
  150. return closedCallback;
  151. }($(this).get(0), result[0].position);
  152. }
  153. }
  154. });
  155. // Callback call.
  156. if (fieldToFocusCallback != null) {
  157. fieldToFocusCallback();
  158. }
  159. }
  160. };
  161. var collectBootstrapCookies = function cookiesRegex() {
  162. var cookies = [],
  163. foundCookies = document.cookie.match(/(?:bs.table.)(\w*)/g);
  164. if (foundCookies) {
  165. $.each(foundCookies, function (i, cookie) {
  166. if (/./.test(cookie)) {
  167. cookie = cookie.split(".").pop();
  168. }
  169. if ($.inArray(cookie, cookies) === -1) {
  170. cookies.push(cookie);
  171. }
  172. });
  173. return cookies;
  174. }
  175. };
  176. var initFilterSelectControls = function initFilterSelectControls(that) {
  177. var data = that.data,
  178. itemsPerPage = that.pageTo < that.options.data.length ? that.options.data.length : that.pageTo,
  179. isColumnSearchableViaSelect = function isColumnSearchableViaSelect(column) {
  180. return column.filterControl && column.filterControl.toLowerCase() === 'select' && column.searchable;
  181. },
  182. isFilterDataNotGiven = function isFilterDataNotGiven(column) {
  183. return column.filterData === undefined || column.filterData.toLowerCase() === 'column';
  184. },
  185. hasSelectControlElement = function hasSelectControlElement(selectControl) {
  186. return selectControl && selectControl.length > 0;
  187. };
  188. var z = that.options.pagination ? that.options.sidePagination === 'server' ? that.pageTo : that.options.totalRows : that.pageTo;
  189. $.each(that.header.fields, function (j, field) {
  190. var column = that.columns[that.fieldsColumnsIndex[field]],
  191. selectControl = $('.bootstrap-table-filter-control-' + escapeID(column.field));
  192. if (isColumnSearchableViaSelect(column) && isFilterDataNotGiven(column) && hasSelectControlElement(selectControl)) {
  193. if (selectControl.get(selectControl.length - 1).options.length === 0) {
  194. //Added the default option
  195. addOptionToSelectControl(selectControl, '', '');
  196. }
  197. var uniqueValues = {};
  198. for (var i = 0; i < z; i++) {
  199. //Added a new value
  200. var fieldValue = data[i][field],
  201. formattedValue = $.fn.bootstrapTable.utils.calculateObjectValue(that.header, that.header.formatters[j], [fieldValue, data[i], i], fieldValue);
  202. uniqueValues[formattedValue] = fieldValue;
  203. }
  204. for (var key in uniqueValues) {
  205. addOptionToSelectControl(selectControl, uniqueValues[key], key);
  206. }
  207. sortSelectControl(selectControl);
  208. if (that.options.hideUnusedSelectOptions) {
  209. hideUnusedSelectOptions(selectControl, uniqueValues);
  210. }
  211. }
  212. });
  213. that.trigger('created-controls');
  214. };
  215. var escapeID = function escapeID(id) {
  216. return String(id).replace(/(:|\.|\[|\]|,)/g, "\\$1");
  217. };
  218. var createControls = function createControls(that, header) {
  219. var addedFilterControl = false,
  220. isVisible,
  221. html;
  222. $.each(that.columns, function (i, column) {
  223. isVisible = 'hidden';
  224. html = [];
  225. if (!column.visible) {
  226. return;
  227. }
  228. if (!column.filterControl) {
  229. html.push('<div class="no-filter-control"></div>');
  230. } else {
  231. html.push('<div class="filter-control">');
  232. var nameControl = column.filterControl.toLowerCase();
  233. if (column.searchable && that.options.filterTemplate[nameControl]) {
  234. addedFilterControl = true;
  235. isVisible = 'visible';
  236. html.push(that.options.filterTemplate[nameControl](that, column.field, isVisible, column.filterControlPlaceholder ? column.filterControlPlaceholder : "", "filter-control-" + i));
  237. }
  238. }
  239. $.each(header.children().children(), function (i, tr) {
  240. tr = $(tr);
  241. if (tr.data('field') === column.field) {
  242. tr.find('.fht-cell').append(html.join(''));
  243. return false;
  244. }
  245. });
  246. if (column.filterData !== undefined && column.filterData.toLowerCase() !== 'column') {
  247. var filterDataType = getFilterDataMethod(filterDataMethods, column.filterData.substring(0, column.filterData.indexOf(':')));
  248. var filterDataSource, selectControl;
  249. if (filterDataType !== null) {
  250. filterDataSource = column.filterData.substring(column.filterData.indexOf(':') + 1, column.filterData.length);
  251. selectControl = $('.bootstrap-table-filter-control-' + escapeID(column.field));
  252. addOptionToSelectControl(selectControl, '', '');
  253. filterDataType(filterDataSource, selectControl);
  254. } else {
  255. throw new SyntaxError('Error. You should use any of these allowed filter data methods: var, json, url.' + ' Use like this: var: {key: "value"}');
  256. }
  257. var variableValues, key;
  258. switch (filterDataType) {
  259. case 'url':
  260. $.ajax({
  261. url: filterDataSource,
  262. dataType: 'json',
  263. success: function success(data) {
  264. for (var key in data) {
  265. addOptionToSelectControl(selectControl, key, data[key]);
  266. }
  267. sortSelectControl(selectControl);
  268. }
  269. });
  270. break;
  271. case 'var':
  272. variableValues = window[filterDataSource];
  273. for (key in variableValues) {
  274. addOptionToSelectControl(selectControl, key, variableValues[key]);
  275. }
  276. sortSelectControl(selectControl);
  277. break;
  278. case 'jso':
  279. variableValues = JSON.parse(filterDataSource);
  280. for (key in variableValues) {
  281. addOptionToSelectControl(selectControl, key, variableValues[key]);
  282. }
  283. sortSelectControl(selectControl);
  284. break;
  285. }
  286. }
  287. });
  288. if (addedFilterControl) {
  289. header.off('keyup', 'input').on('keyup', 'input', function (event) {
  290. if (that.options.searchOnEnterKey && event.keyCode !== 13) {
  291. return;
  292. }
  293. if ($.inArray(event.keyCode, [37, 38, 39, 40]) > -1) {
  294. return;
  295. }
  296. clearTimeout(event.currentTarget.timeoutId || 0);
  297. event.currentTarget.timeoutId = setTimeout(function () {
  298. that.onColumnSearch(event);
  299. }, that.options.searchTimeOut);
  300. });
  301. header.off('change', 'select').on('change', 'select', function (event) {
  302. if (that.options.searchOnEnterKey && event.keyCode !== 13) {
  303. return;
  304. }
  305. if ($.inArray(event.keyCode, [37, 38, 39, 40]) > -1) {
  306. return;
  307. }
  308. clearTimeout(event.currentTarget.timeoutId || 0);
  309. event.currentTarget.timeoutId = setTimeout(function () {
  310. that.onColumnSearch(event);
  311. }, that.options.searchTimeOut);
  312. });
  313. header.off('mouseup', 'input').on('mouseup', 'input', function (event) {
  314. var $input = $(this),
  315. oldValue = $input.val();
  316. if (oldValue === "") {
  317. return;
  318. }
  319. setTimeout(function () {
  320. var newValue = $input.val();
  321. if (newValue === "") {
  322. clearTimeout(event.currentTarget.timeoutId || 0);
  323. event.currentTarget.timeoutId = setTimeout(function () {
  324. that.onColumnSearch(event);
  325. }, that.options.searchTimeOut);
  326. }
  327. }, 1);
  328. });
  329. if (header.find('.date-filter-control').length > 0) {
  330. $.each(that.columns, function (i, column) {
  331. if (column.filterControl !== undefined && column.filterControl.toLowerCase() === 'datepicker') {
  332. header.find('.date-filter-control.bootstrap-table-filter-control-' + column.field).datepicker(column.filterDatepickerOptions).on('changeDate', function (e) {
  333. $(sprintf("#%s", e.currentTarget.id)).val(e.currentTarget.value);
  334. //Fired the keyup event
  335. $(e.currentTarget).keyup();
  336. });
  337. }
  338. });
  339. }
  340. } else {
  341. header.find('.filterControl').hide();
  342. }
  343. };
  344. var getDirectionOfSelectOptions = function getDirectionOfSelectOptions(alignment) {
  345. alignment = alignment === undefined ? 'left' : alignment.toLowerCase();
  346. switch (alignment) {
  347. case 'left':
  348. return 'ltr';
  349. case 'right':
  350. return 'rtl';
  351. case 'auto':
  352. return 'auto';
  353. default:
  354. return 'ltr';
  355. }
  356. };
  357. var filterDataMethods = {
  358. 'var': function _var(filterDataSource, selectControl) {
  359. var variableValues = window[filterDataSource];
  360. for (var key in variableValues) {
  361. addOptionToSelectControl(selectControl, key, variableValues[key]);
  362. }
  363. sortSelectControl(selectControl);
  364. },
  365. 'url': function url(filterDataSource, selectControl) {
  366. $.ajax({
  367. url: filterDataSource,
  368. dataType: 'json',
  369. success: function success(data) {
  370. for (var key in data) {
  371. addOptionToSelectControl(selectControl, key, data[key]);
  372. }
  373. sortSelectControl(selectControl);
  374. }
  375. });
  376. },
  377. 'json': function json(filterDataSource, selectControl) {
  378. var variableValues = JSON.parse(filterDataSource);
  379. for (var key in variableValues) {
  380. addOptionToSelectControl(selectControl, key, variableValues[key]);
  381. }
  382. sortSelectControl(selectControl);
  383. }
  384. };
  385. var getFilterDataMethod = function getFilterDataMethod(objFilterDataMethod, searchTerm) {
  386. var keys = Object.keys(objFilterDataMethod);
  387. for (var i = 0; i < keys.length; i++) {
  388. if (keys[i] === searchTerm) {
  389. return objFilterDataMethod[searchTerm];
  390. }
  391. }
  392. return null;
  393. };
  394. $.extend($.fn.bootstrapTable.defaults, {
  395. filterControl: false,
  396. onColumnSearch: function onColumnSearch(field, text) {
  397. return false;
  398. },
  399. onCreatedControls: function onCreatedControls() {
  400. return true;
  401. },
  402. filterShowClear: false,
  403. alignmentSelectControlOptions: undefined,
  404. filterTemplate: {
  405. input: function input(that, field, isVisible, placeholder) {
  406. return sprintf('<input type="text" class="form-control bootstrap-table-filter-control-%s" style="width: 100%; visibility: %s" placeholder="%s">', field, isVisible, placeholder);
  407. },
  408. select: function select(that, field, isVisible) {
  409. return sprintf('<select class="form-control bootstrap-table-filter-control-%s" style="width: 100%; visibility: %s" dir="%s"></select>', field, isVisible, getDirectionOfSelectOptions(that.options.alignmentSelectControlOptions));
  410. },
  411. datepicker: function datepicker(that, field, isVisible) {
  412. return sprintf('<input type="text" class="form-control date-filter-control bootstrap-table-filter-control-%s" style="width: 100%; visibility: %s">', field, isVisible);
  413. }
  414. },
  415. disableControlWhenSearch: false,
  416. searchOnEnterKey: false,
  417. //internal variables
  418. valuesFilterControl: []
  419. });
  420. $.extend($.fn.bootstrapTable.columnDefaults, {
  421. filterControl: undefined,
  422. filterData: undefined,
  423. filterDatepickerOptions: undefined,
  424. filterStrictSearch: false,
  425. filterStartsWithSearch: false,
  426. filterControlPlaceholder: ""
  427. });
  428. $.extend($.fn.bootstrapTable.Constructor.EVENTS, {
  429. 'column-search.bs.table': 'onColumnSearch',
  430. 'created-controls.bs.table': 'onCreatedControls'
  431. });
  432. $.extend($.fn.bootstrapTable.defaults.icons, {
  433. clear: 'glyphicon-trash icon-clear'
  434. });
  435. $.extend($.fn.bootstrapTable.locales, {
  436. formatClearFilters: function formatClearFilters() {
  437. return 'Clear Filters';
  438. }
  439. });
  440. $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales);
  441. $.fn.bootstrapTable.methods.push('triggerSearch');
  442. var BootstrapTable = $.fn.bootstrapTable.Constructor,
  443. _init = BootstrapTable.prototype.init,
  444. _initToolbar = BootstrapTable.prototype.initToolbar,
  445. _initHeader = BootstrapTable.prototype.initHeader,
  446. _initBody = BootstrapTable.prototype.initBody,
  447. _initSearch = BootstrapTable.prototype.initSearch;
  448. BootstrapTable.prototype.init = function () {
  449. //Make sure that the filterControl option is set
  450. if (this.options.filterControl) {
  451. var that = this;
  452. // Compatibility: IE < 9 and old browsers
  453. if (!Object.keys) {
  454. objectKeys();
  455. }
  456. //Make sure that the internal variables are set correctly
  457. this.options.valuesFilterControl = [];
  458. this.$el.on('reset-view.bs.table', function () {
  459. //Create controls on $tableHeader if the height is set
  460. if (!that.options.height) {
  461. return;
  462. }
  463. //Avoid recreate the controls
  464. if (that.$tableHeader.find('select').length > 0 || that.$tableHeader.find('input').length > 0) {
  465. return;
  466. }
  467. createControls(that, that.$tableHeader);
  468. }).on('post-header.bs.table', function () {
  469. setValues(that);
  470. }).on('post-body.bs.table', function () {
  471. if (that.options.height) {
  472. fixHeaderCSS(that);
  473. }
  474. }).on('column-switch.bs.table', function () {
  475. setValues(that);
  476. }).on('load-success.bs.table', function () {
  477. that.EnableControls(true);
  478. }).on('load-error.bs.table', function () {
  479. that.EnableControls(true);
  480. });
  481. }
  482. _init.apply(this, Array.prototype.slice.apply(arguments));
  483. };
  484. BootstrapTable.prototype.initToolbar = function () {
  485. this.showToolbar = this.showToolbar || this.options.filterControl && this.options.filterShowClear;
  486. _initToolbar.apply(this, Array.prototype.slice.apply(arguments));
  487. if (this.options.filterControl && this.options.filterShowClear) {
  488. var $btnGroup = this.$toolbar.find('>.btn-group'),
  489. $btnClear = $btnGroup.find('.filter-show-clear');
  490. if (!$btnClear.length) {
  491. $btnClear = $([sprintf('<button class="btn btn-%s filter-show-clear" ', this.options.buttonsClass), sprintf('type="button" title="%s">', this.options.formatClearFilters()), sprintf('<i class="%s %s"></i> ', this.options.iconsPrefix, this.options.icons.clear), '</button>'].join('')).appendTo($btnGroup);
  492. $btnClear.off('click').on('click', $.proxy(this.clearFilterControl, this));
  493. }
  494. }
  495. };
  496. BootstrapTable.prototype.initHeader = function () {
  497. _initHeader.apply(this, Array.prototype.slice.apply(arguments));
  498. if (!this.options.filterControl) {
  499. return;
  500. }
  501. createControls(this, this.$header);
  502. };
  503. BootstrapTable.prototype.initBody = function () {
  504. _initBody.apply(this, Array.prototype.slice.apply(arguments));
  505. initFilterSelectControls(this);
  506. };
  507. BootstrapTable.prototype.initSearch = function () {
  508. _initSearch.apply(this, Array.prototype.slice.apply(arguments));
  509. if (this.options.sidePagination === 'server') {
  510. return;
  511. }
  512. var that = this;
  513. var fp = $.isEmptyObject(that.filterColumnsPartial) ? null : that.filterColumnsPartial;
  514. //Check partial column filter
  515. that.data = fp ? $.grep(that.data, function (item, i) {
  516. for (var key in fp) {
  517. var thisColumn = that.columns[that.fieldsColumnsIndex[key]];
  518. var fval = fp[key].toLowerCase();
  519. var value = item[key];
  520. // Fix #142: search use formated data
  521. if (thisColumn && thisColumn.searchFormatter) {
  522. value = $.fn.bootstrapTable.utils.calculateObjectValue(that.header, that.header.formatters[$.inArray(key, that.header.fields)], [value, item, i], value);
  523. }
  524. if ($.inArray(key, that.header.fields) !== -1) {
  525. if (typeof value === 'string' || typeof value === 'number') {
  526. if (thisColumn.filterStrictSearch) {
  527. if (value.toString().toLowerCase() === fval.toString().toLowerCase()) {
  528. return true;
  529. }
  530. } else if (thisColumn.filterStartsWithSearch) {
  531. if ((value + '').toLowerCase().indexOf(fval) === 0) {
  532. return true;
  533. }
  534. } else {
  535. if ((value + '').toLowerCase().indexOf(fval) !== -1) {
  536. return true;
  537. }
  538. }
  539. }
  540. }
  541. }
  542. return false;
  543. }) : that.data;
  544. };
  545. BootstrapTable.prototype.initColumnSearch = function (filterColumnsDefaults) {
  546. copyValues(this);
  547. if (filterColumnsDefaults) {
  548. this.filterColumnsPartial = filterColumnsDefaults;
  549. this.updatePagination();
  550. for (var filter in filterColumnsDefaults) {
  551. this.trigger('column-search', filter, filterColumnsDefaults[filter]);
  552. }
  553. }
  554. };
  555. BootstrapTable.prototype.onColumnSearch = function (event) {
  556. if ($.inArray(event.keyCode, [37, 38, 39, 40]) > -1) {
  557. return;
  558. }
  559. copyValues(this);
  560. var text = $.trim($(event.currentTarget).val());
  561. var $field = $(event.currentTarget).closest('[data-field]').data('field');
  562. if ($.isEmptyObject(this.filterColumnsPartial)) {
  563. this.filterColumnsPartial = {};
  564. }
  565. if (text) {
  566. this.filterColumnsPartial[$field] = text;
  567. } else {
  568. delete this.filterColumnsPartial[$field];
  569. }
  570. // if the searchText is the same as the previously selected column value,
  571. // bootstrapTable will not try searching again (even though the selected column
  572. // may be different from the previous search). As a work around
  573. // we're manually appending some text to bootrap's searchText field
  574. // to guarantee that it will perform a search again when we call this.onSearch(event)
  575. this.searchText += "randomText";
  576. this.options.pageNumber = 1;
  577. this.EnableControls(false);
  578. this.onSearch(event);
  579. this.trigger('column-search', $field, text);
  580. };
  581. BootstrapTable.prototype.clearFilterControl = function () {
  582. if (this.options.filterControl && this.options.filterShowClear) {
  583. var that = this,
  584. cookies = collectBootstrapCookies(),
  585. header = getCurrentHeader(that),
  586. table = header.closest('table'),
  587. controls = header.find(getCurrentSearchControls(that)),
  588. search = that.$toolbar.find('.search input'),
  589. hasValues = false,
  590. timeoutId = 0;
  591. $.each(that.options.valuesFilterControl, function (i, item) {
  592. hasValues = hasValues ? true : item.value !== '';
  593. item.value = '';
  594. });
  595. setValues(that);
  596. // clear cookies once the filters are clean
  597. clearTimeout(timeoutId);
  598. timeoutId = setTimeout(function () {
  599. if (cookies && cookies.length > 0) {
  600. $.each(cookies, function (i, item) {
  601. if (that.deleteCookie !== undefined) {
  602. that.deleteCookie(item);
  603. }
  604. });
  605. }
  606. }, that.options.searchTimeOut);
  607. //If there is not any value in the controls exit this method
  608. if (!hasValues) {
  609. return;
  610. }
  611. // Clear each type of filter if it exists.
  612. // Requires the body to reload each time a type of filter is found because we never know
  613. // which ones are going to be present.
  614. if (controls.length > 0) {
  615. this.filterColumnsPartial = {};
  616. $(controls[0]).trigger(controls[0].tagName === 'INPUT' ? 'keyup' : 'change');
  617. } else {
  618. return;
  619. }
  620. if (search.length > 0) {
  621. that.resetSearch();
  622. }
  623. // use the default sort order if it exists. do nothing if it does not
  624. if (that.options.sortName !== table.data('sortName') || that.options.sortOrder !== table.data('sortOrder')) {
  625. var sorter = header.find(sprintf('[data-field="%s"]', $(controls[0]).closest('table').data('sortName')));
  626. if (sorter.length > 0) {
  627. that.onSort({ type: 'keypress', currentTarget: sorter });
  628. $(sorter).find('.sortable').trigger('click');
  629. }
  630. }
  631. }
  632. };
  633. BootstrapTable.prototype.triggerSearch = function () {
  634. var header = getCurrentHeader(this),
  635. searchControls = getCurrentSearchControls(this);
  636. header.find(searchControls).each(function () {
  637. var el = $(this);
  638. if (el.is('select')) {
  639. el.change();
  640. } else {
  641. el.keyup();
  642. }
  643. });
  644. };
  645. BootstrapTable.prototype.EnableControls = function (enable) {
  646. if (this.options.disableControlWhenSearch && this.options.sidePagination === 'server') {
  647. var header = getCurrentHeader(this),
  648. searchControls = getCurrentSearchControls(this);
  649. if (!enable) {
  650. header.find(searchControls).prop('disabled', 'disabled');
  651. } else {
  652. header.find(searchControls).removeProp('disabled');
  653. }
  654. }
  655. };
  656. })(jQuery);
  657. });