bootstrap-table-group-by.js 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  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.bootstrapTableGroupBy = mod.exports;
  12. }
  13. })(this, function () {
  14. 'use strict';
  15. /**
  16. * @author: Yura Knoxville
  17. * @version: v1.1.0
  18. */
  19. (function ($) {
  20. 'use strict';
  21. var initBodyCaller, tableGroups;
  22. // it only does '%s', and return '' when arguments are undefined
  23. var sprintf = function sprintf(str) {
  24. var args = arguments,
  25. flag = true,
  26. i = 1;
  27. str = str.replace(/%s/g, function () {
  28. var arg = args[i++];
  29. if (typeof arg === 'undefined') {
  30. flag = false;
  31. return '';
  32. }
  33. return arg;
  34. });
  35. return flag ? str : '';
  36. };
  37. var groupBy = function groupBy(array, f) {
  38. var groups = {};
  39. array.forEach(function (o) {
  40. var group = f(o);
  41. groups[group] = groups[group] || [];
  42. groups[group].push(o);
  43. });
  44. return groups;
  45. };
  46. $.extend($.fn.bootstrapTable.defaults, {
  47. groupBy: false,
  48. groupByField: '',
  49. groupByFormatter: undefined
  50. });
  51. var BootstrapTable = $.fn.bootstrapTable.Constructor,
  52. _initSort = BootstrapTable.prototype.initSort,
  53. _initBody = BootstrapTable.prototype.initBody,
  54. _updateSelected = BootstrapTable.prototype.updateSelected;
  55. BootstrapTable.prototype.initSort = function () {
  56. _initSort.apply(this, Array.prototype.slice.apply(arguments));
  57. var that = this;
  58. tableGroups = [];
  59. if (this.options.groupBy && this.options.groupByField !== '') {
  60. if (this.options.sortName != this.options.groupByField) {
  61. this.data.sort(function (a, b) {
  62. return a[that.options.groupByField].localeCompare(b[that.options.groupByField]);
  63. });
  64. }
  65. var that = this;
  66. var groups = groupBy(that.data, function (item) {
  67. return [item[that.options.groupByField]];
  68. });
  69. var index = 0;
  70. $.each(groups, function (key, value) {
  71. tableGroups.push({
  72. id: index,
  73. name: key,
  74. data: value
  75. });
  76. value.forEach(function (item) {
  77. if (!item._data) {
  78. item._data = {};
  79. }
  80. item._data['parent-index'] = index;
  81. });
  82. index++;
  83. });
  84. }
  85. };
  86. BootstrapTable.prototype.initBody = function () {
  87. initBodyCaller = true;
  88. _initBody.apply(this, Array.prototype.slice.apply(arguments));
  89. if (this.options.groupBy && this.options.groupByField !== '') {
  90. var that = this,
  91. checkBox = false,
  92. visibleColumns = 0;
  93. this.columns.forEach(function (column) {
  94. if (column.checkbox) {
  95. checkBox = true;
  96. } else {
  97. if (column.visible) {
  98. visibleColumns += 1;
  99. }
  100. }
  101. });
  102. if (this.options.detailView && !this.options.cardView) {
  103. visibleColumns += 1;
  104. }
  105. tableGroups.forEach(function (item) {
  106. var html = [];
  107. html.push(sprintf('<tr class="info groupBy expanded" data-group-index="%s">', item.id));
  108. if (that.options.detailView && !that.options.cardView) {
  109. html.push('<td class="detail"></td>');
  110. }
  111. if (checkBox) {
  112. html.push('<td class="bs-checkbox">', '<input name="btSelectGroup" type="checkbox" />', '</td>');
  113. }
  114. var formattedValue = item.name;
  115. if (typeof that.options.groupByFormatter == "function") {
  116. formattedValue = that.options.groupByFormatter(item.name, item.id, item.data);
  117. }
  118. html.push('<td', sprintf(' colspan="%s"', visibleColumns), '>', formattedValue, '</td>');
  119. html.push('</tr>');
  120. that.$body.find('tr[data-parent-index=' + item.id + ']:first').before($(html.join('')));
  121. });
  122. this.$selectGroup = [];
  123. this.$body.find('[name="btSelectGroup"]').each(function () {
  124. var self = $(this);
  125. that.$selectGroup.push({
  126. group: self,
  127. item: that.$selectItem.filter(function () {
  128. return $(this).closest('tr').data('parent-index') === self.closest('tr').data('group-index');
  129. })
  130. });
  131. });
  132. this.$container.off('click', '.groupBy').on('click', '.groupBy', function () {
  133. $(this).toggleClass('expanded');
  134. that.$body.find('tr[data-parent-index=' + $(this).closest('tr').data('group-index') + ']').toggleClass('hidden');
  135. });
  136. this.$container.off('click', '[name="btSelectGroup"]').on('click', '[name="btSelectGroup"]', function (event) {
  137. event.stopImmediatePropagation();
  138. var self = $(this);
  139. var checked = self.prop('checked');
  140. that[checked ? 'checkGroup' : 'uncheckGroup']($(this).closest('tr').data('group-index'));
  141. });
  142. }
  143. initBodyCaller = false;
  144. this.updateSelected();
  145. };
  146. BootstrapTable.prototype.updateSelected = function () {
  147. if (!initBodyCaller) {
  148. _updateSelected.apply(this, Array.prototype.slice.apply(arguments));
  149. if (this.options.groupBy && this.options.groupByField !== '') {
  150. this.$selectGroup.forEach(function (item) {
  151. var checkGroup = item.item.filter(':enabled').length === item.item.filter(':enabled').filter(':checked').length;
  152. item.group.prop('checked', checkGroup);
  153. });
  154. }
  155. }
  156. };
  157. BootstrapTable.prototype.getGroupSelections = function (index) {
  158. var that = this;
  159. return $.grep(this.data, function (row) {
  160. return row[that.header.stateField] && row._data['parent-index'] === index;
  161. });
  162. };
  163. BootstrapTable.prototype.checkGroup = function (index) {
  164. this.checkGroup_(index, true);
  165. };
  166. BootstrapTable.prototype.uncheckGroup = function (index) {
  167. this.checkGroup_(index, false);
  168. };
  169. BootstrapTable.prototype.checkGroup_ = function (index, checked) {
  170. var rows;
  171. var filter = function filter() {
  172. return $(this).closest('tr').data('parent-index') === index;
  173. };
  174. if (!checked) {
  175. rows = this.getGroupSelections(index);
  176. }
  177. this.$selectItem.filter(filter).prop('checked', checked);
  178. this.updateRows();
  179. this.updateSelected();
  180. if (checked) {
  181. rows = this.getGroupSelections(index);
  182. }
  183. this.trigger(checked ? 'check-all' : 'uncheck-all', rows);
  184. };
  185. })(jQuery);
  186. });