bootstrap-table-group-by.js 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  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.0.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. });
  50. var BootstrapTable = $.fn.bootstrapTable.Constructor,
  51. _initSort = BootstrapTable.prototype.initSort,
  52. _initBody = BootstrapTable.prototype.initBody,
  53. _updateSelected = BootstrapTable.prototype.updateSelected;
  54. BootstrapTable.prototype.initSort = function () {
  55. _initSort.apply(this, Array.prototype.slice.apply(arguments));
  56. var that = this;
  57. tableGroups = [];
  58. if (this.options.groupBy && this.options.groupByField !== '') {
  59. if (this.options.sortName != this.options.groupByField) {
  60. this.data.sort(function (a, b) {
  61. return a[that.options.groupByField].localeCompare(b[that.options.groupByField]);
  62. });
  63. }
  64. var that = this;
  65. var groups = groupBy(that.data, function (item) {
  66. return [item[that.options.groupByField]];
  67. });
  68. var index = 0;
  69. $.each(groups, function (key, value) {
  70. tableGroups.push({
  71. id: index,
  72. name: key
  73. });
  74. value.forEach(function (item) {
  75. if (!item._data) {
  76. item._data = {};
  77. }
  78. item._data['parent-index'] = index;
  79. });
  80. index++;
  81. });
  82. }
  83. };
  84. BootstrapTable.prototype.initBody = function () {
  85. initBodyCaller = true;
  86. _initBody.apply(this, Array.prototype.slice.apply(arguments));
  87. if (this.options.groupBy && this.options.groupByField !== '') {
  88. var that = this,
  89. checkBox = false,
  90. visibleColumns = 0;
  91. this.columns.forEach(function (column) {
  92. if (column.checkbox) {
  93. checkBox = true;
  94. } else {
  95. if (column.visible) {
  96. visibleColumns += 1;
  97. }
  98. }
  99. });
  100. if (this.options.detailView && !this.options.cardView) {
  101. visibleColumns += 1;
  102. }
  103. tableGroups.forEach(function (item) {
  104. var html = [];
  105. html.push(sprintf('<tr class="info groupBy expanded" data-group-index="%s">', item.id));
  106. if (that.options.detailView && !that.options.cardView) {
  107. html.push('<td class="detail"></td>');
  108. }
  109. if (checkBox) {
  110. html.push('<td class="bs-checkbox">', '<input name="btSelectGroup" type="checkbox" />', '</td>');
  111. }
  112. html.push('<td', sprintf(' colspan="%s"', visibleColumns), '>', item.name, '</td>');
  113. html.push('</tr>');
  114. that.$body.find('tr[data-parent-index=' + item.id + ']:first').before($(html.join('')));
  115. });
  116. this.$selectGroup = [];
  117. this.$body.find('[name="btSelectGroup"]').each(function () {
  118. var self = $(this);
  119. that.$selectGroup.push({
  120. group: self,
  121. item: that.$selectItem.filter(function () {
  122. return $(this).closest('tr').data('parent-index') === self.closest('tr').data('group-index');
  123. })
  124. });
  125. });
  126. this.$container.off('click', '.groupBy').on('click', '.groupBy', function () {
  127. $(this).toggleClass('expanded');
  128. that.$body.find('tr[data-parent-index=' + $(this).closest('tr').data('group-index') + ']').toggleClass('hidden');
  129. });
  130. this.$container.off('click', '[name="btSelectGroup"]').on('click', '[name="btSelectGroup"]', function (event) {
  131. event.stopImmediatePropagation();
  132. var self = $(this);
  133. var checked = self.prop('checked');
  134. that[checked ? 'checkGroup' : 'uncheckGroup']($(this).closest('tr').data('group-index'));
  135. });
  136. }
  137. initBodyCaller = false;
  138. this.updateSelected();
  139. };
  140. BootstrapTable.prototype.updateSelected = function () {
  141. if (!initBodyCaller) {
  142. _updateSelected.apply(this, Array.prototype.slice.apply(arguments));
  143. if (this.options.groupBy && this.options.groupByField !== '') {
  144. this.$selectGroup.forEach(function (item) {
  145. var checkGroup = item.item.filter(':enabled').length === item.item.filter(':enabled').filter(':checked').length;
  146. item.group.prop('checked', checkGroup);
  147. });
  148. }
  149. }
  150. };
  151. BootstrapTable.prototype.getGroupSelections = function (index) {
  152. var that = this;
  153. return $.grep(this.data, function (row) {
  154. return row[that.header.stateField] && row._data['parent-index'] === index;
  155. });
  156. };
  157. BootstrapTable.prototype.checkGroup = function (index) {
  158. this.checkGroup_(index, true);
  159. };
  160. BootstrapTable.prototype.uncheckGroup = function (index) {
  161. this.checkGroup_(index, false);
  162. };
  163. BootstrapTable.prototype.checkGroup_ = function (index, checked) {
  164. var rows;
  165. var filter = function filter() {
  166. return $(this).closest('tr').data('parent-index') === index;
  167. };
  168. if (!checked) {
  169. rows = this.getGroupSelections(index);
  170. }
  171. this.$selectItem.filter(filter).prop('checked', checked);
  172. this.updateRows();
  173. this.updateSelected();
  174. if (checked) {
  175. rows = this.getGroupSelections(index);
  176. }
  177. this.trigger(checked ? 'check-all' : 'uncheck-all', rows);
  178. };
  179. }(jQuery);
  180. });