bootstrap-table-filter-control.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. /**
  2. * @author: Dennis Hernández
  3. * @webSite: http://djhvscf.github.io/Blog
  4. * @version: v1.0.0
  5. */
  6. !function ($) {
  7. 'use strict';
  8. var sprintf = function (str) {
  9. var args = arguments,
  10. flag = true,
  11. i = 1;
  12. str = str.replace(/%s/g, function () {
  13. var arg = args[i++];
  14. if (typeof arg === 'undefined') {
  15. flag = false;
  16. return '';
  17. }
  18. return arg;
  19. });
  20. return flag ? str : '';
  21. };
  22. var getFieldIndex = function (columns, field) {
  23. var index = -1;
  24. $.each(columns, function (i, column) {
  25. if (column.field === field) {
  26. index = i;
  27. return false;
  28. }
  29. return true;
  30. });
  31. return index;
  32. };
  33. var calculateObjectValue = function (self, name, args, defaultValue) {
  34. if (typeof name === 'string') {
  35. // support obj.func1.func2
  36. var names = name.split('.');
  37. if (names.length > 1) {
  38. name = window;
  39. $.each(names, function (i, f) {
  40. name = name[f];
  41. });
  42. } else {
  43. name = window[name];
  44. }
  45. }
  46. if (typeof name === 'object') {
  47. return name;
  48. }
  49. if (typeof name === 'function') {
  50. return name.apply(self, args);
  51. }
  52. return defaultValue;
  53. };
  54. $.extend($.fn.bootstrapTable.defaults, {
  55. filterControl: false,
  56. onColumnSearch: function (field, text) {
  57. return false;
  58. }
  59. });
  60. $.extend($.fn.bootstrapTable.COLUMN_DEFAULTS, {
  61. filterControl: undefined,
  62. filterData: undefined
  63. });
  64. $.extend($.fn.bootstrapTable.Constructor.EVENTS, {
  65. 'column-search.bs.table': 'onColumnSearch'
  66. });
  67. var BootstrapTable = $.fn.bootstrapTable.Constructor,
  68. _initHeader = BootstrapTable.prototype.initHeader,
  69. _initBody = BootstrapTable.prototype.initBody,
  70. _initSearch = BootstrapTable.prototype.initSearch;
  71. BootstrapTable.prototype.initHeader = function () {
  72. _initHeader.apply(this, Array.prototype.slice.apply(arguments));
  73. if (!this.options.filterControl) {
  74. return;
  75. }
  76. var addedFilterControl = false,
  77. that = this,
  78. isVisible,
  79. html,
  80. timeoutId = 0;
  81. $.each(this.options.columns, function (i, column) {
  82. isVisible = 'hidden';
  83. html = [];
  84. if (!column.visible) {
  85. return;
  86. }
  87. if (!column.filterControl) {
  88. html.push('<div style="height: 34px;"></div>');
  89. } else {
  90. html.push('<div style="margin: 0px 2px 2px 2px;" class="filterControl">');
  91. if (column.filterControl && column.searchable) {
  92. addedFilterControl = true;
  93. isVisible = 'visible'
  94. }
  95. switch (column.filterControl.toLowerCase()) {
  96. case 'input' :
  97. html.push(sprintf('<input type="text" class="form-control" style="width: 100%; visibility: %s">', isVisible));
  98. break;
  99. case 'select':
  100. html.push(sprintf('<select class="%s form-control" style="width: 100%; visibility: %s"></select>',
  101. column.field, isVisible))
  102. break;
  103. }
  104. }
  105. that.$header.find(sprintf('.th-inner:eq("%s")', i)).next().append(html.join(''));
  106. if (column.filterData !== undefined && column.filterData.toLowerCase() !== 'column') {
  107. var filterDataType = column.filterData.substring(0, 3);
  108. var filterDataSource = column.filterData.substring(4, column.filterData.length);
  109. var selectControl = $('.' + column.field);
  110. selectControl.append($("<option></option>")
  111. .attr("value", '')
  112. .text(''));
  113. switch (filterDataType) {
  114. case 'url':
  115. $.ajax({
  116. url: filterDataSource,
  117. dataType: 'json',
  118. success: function (data) {
  119. $.each(data, function (key, value) {
  120. selectControl.append($("<option></option>")
  121. .attr("value", key)
  122. .text(value));
  123. });
  124. }
  125. });
  126. break;
  127. case 'var':
  128. var variableValues = window[filterDataSource];
  129. for (var key in variableValues) {
  130. selectControl.append($("<option></option>")
  131. .attr("value", key)
  132. .text(variableValues[key]));
  133. };
  134. break;
  135. }
  136. }
  137. });
  138. if (addedFilterControl) {
  139. this.$header.off('keyup', 'input').on('keyup', 'input', function (event) {
  140. clearTimeout(timeoutId);
  141. timeoutId = setTimeout(function () {
  142. that.onColumnSearch(event);
  143. }, that.options.searchTimeOut);
  144. });
  145. this.$header.off('change', 'select').on('change', 'select', function (event) {
  146. clearTimeout(timeoutId);
  147. timeoutId = setTimeout(function () {
  148. that.onColumnSearch(event);
  149. }, that.options.searchTimeOut);
  150. });
  151. } else {
  152. this.$header.find('.filterControl').hide();
  153. }
  154. };
  155. BootstrapTable.prototype.initBody = function () {
  156. _initBody.apply(this, Array.prototype.slice.apply(arguments));
  157. var that = this,
  158. data = this.getData();
  159. for (var i = this.pageFrom - 1; i < this.pageTo; i++) {
  160. var key,
  161. item = data[i];
  162. $.each(this.header.fields, function (j, field) {
  163. var value = item[field],
  164. column = that.options.columns[getFieldIndex(that.options.columns, field)];
  165. value = calculateObjectValue(that.header,
  166. that.header.formatters[j], [value, item, i], value);
  167. if ((!column.checkbox) || (!column.radio)) {
  168. if (column.filterControl !== undefined && column.filterControl.toLowerCase() === 'select'
  169. && column.searchable) {
  170. if (column.filterData === undefined || column.filterData.toLowerCase() === 'column') {
  171. var selectControl = $('.' + column.field),
  172. iOpt = 0,
  173. exitsOpt = false,
  174. options;
  175. if (selectControl !== undefined) {
  176. options = selectControl.get(0).options;
  177. if (options.length === 0) {
  178. //Added the default option
  179. selectControl.append($("<option></option>")
  180. .attr("value", '')
  181. .text(''));
  182. selectControl.append($("<option></option>")
  183. .attr("value", value)
  184. .text(value));
  185. } else {
  186. for (; iOpt < options.length; iOpt++) {
  187. if (options[iOpt].value === value) {
  188. exitsOpt = true;
  189. break;
  190. }
  191. }
  192. if (!exitsOpt) {
  193. selectControl.append($("<option></option>")
  194. .attr("value", value)
  195. .text(value));
  196. }
  197. }
  198. }
  199. }
  200. }
  201. }
  202. });
  203. }
  204. };
  205. BootstrapTable.prototype.initSearch = function () {
  206. _initSearch.apply(this, Array.prototype.slice.apply(arguments));
  207. var that = this;
  208. var fp = $.isEmptyObject(this.filterColumnsPartial) ? null : this.filterColumnsPartial;
  209. //Check partial column filter
  210. this.data = fp ? $.grep(this.data, function (item, i) {
  211. for (var key in fp) {
  212. var fval = fp[key].toLowerCase();
  213. var value = item[key];
  214. value = calculateObjectValue(that.header,
  215. that.header.formatters[$.inArray(key, that.header.fields)],
  216. [value, item, i], value);
  217. if (!($.inArray(key, that.header.fields) !== -1 &&
  218. (typeof value === 'string' || typeof value === 'number') &&
  219. (value + '').toLowerCase().indexOf(fval) !== -1)) {
  220. return false;
  221. }
  222. }
  223. return true;
  224. }) : this.data;
  225. };
  226. BootstrapTable.prototype.onColumnSearch = function (event) {
  227. var text = $.trim($(event.currentTarget).val());
  228. var $field = $(event.currentTarget).parent().parent().parent().data('field')
  229. if ($.isEmptyObject(this.filterColumnsPartial)) {
  230. this.filterColumnsPartial = {};
  231. }
  232. if (text) {
  233. this.filterColumnsPartial[$field] = text;
  234. } else {
  235. delete this.filterColumnsPartial[$field];
  236. }
  237. this.options.pageNumber = 1;
  238. this.onSearch(event);
  239. this.updatePagination();
  240. this.trigger('column-search', $field, text);
  241. };
  242. }(jQuery);