bootstrap-table-group-by.js 6.8 KB

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