/** * @author: Yura Knoxville * @version: v1.0.0 */ !function ($) { 'use strict'; var initBodyCaller, tableGroups; // it only does '%s', and return '' when arguments are undefined var sprintf = function (str) { var args = arguments, flag = true, i = 1; str = str.replace(/%s/g, function () { var arg = args[i++]; if (typeof arg === 'undefined') { flag = false; return ''; } return arg; }); return flag ? str : ''; }; var groupBy = function (array , f) { var groups = {}; array.forEach(function(o) { var group = f(o); groups[group] = groups[group] || []; groups[group].push(o); }); return groups; }; $.extend($.fn.bootstrapTable.defaults, { groupBy: false, groupByField: '' }); var BootstrapTable = $.fn.bootstrapTable.Constructor, _initSort = BootstrapTable.prototype.initSort, _initBody = BootstrapTable.prototype.initBody, _updateSelected = BootstrapTable.prototype.updateSelected; BootstrapTable.prototype.initSort = function () { _initSort.apply(this, Array.prototype.slice.apply(arguments)); var that = this; tableGroups = []; if ((this.options.groupBy) && (this.options.groupByField !== '')) { if ((this.options.sortName != this.options.groupByField)) { this.data.sort(function(a, b) { return a[that.options.groupByField].localeCompare(b[that.options.groupByField]); }); } var that = this; var groups = groupBy(that.data, function (item) { return [item[that.options.groupByField]]; }); var index = 0; $.each(groups, function(key, value) { tableGroups.push({ id: index, name: key }); value.forEach(function(item) { if (!item._data) { item._data = {}; } item._data['parent-index'] = index; }); index++; }); } } BootstrapTable.prototype.initBody = function () { initBodyCaller = true; _initBody.apply(this, Array.prototype.slice.apply(arguments)); if ((this.options.groupBy) && (this.options.groupByField !== '')) { var that = this, checkBox = false, visibleColumns = 0; this.columns.forEach(function(column) { if (column.checkbox) { checkBox = true; } else { if (column.visible) { visibleColumns += 1; } } }); if (this.options.detailView && !this.options.cardView) { visibleColumns += 1; } tableGroups.forEach(function(item){ var html = []; html.push(sprintf('', item.id)); if (that.options.detailView && !that.options.cardView) { html.push(''); } if (checkBox) { html.push('', '', '' ); } html.push('', item.name, '' ); html.push(''); that.$body.find('tr[data-parent-index='+item.id+']:first').before($(html.join(''))); }); this.$selectGroup = []; this.$body.find('[name="btSelectGroup"]').each(function() { var self = $(this); that.$selectGroup.push({ group: self, item: that.$selectItem.filter(function () { return ($(this).closest('tr').data('parent-index') === self.closest('tr').data('group-index')); }) }); }); this.$container.off('click', '.groupBy') .on('click', '.groupBy', function() { $(this).toggleClass('expanded'); that.$body.find('tr[data-parent-index='+$(this).closest('tr').data('group-index')+']').toggleClass('hidden'); }); this.$container.off('click', '[name="btSelectGroup"]') .on('click', '[name="btSelectGroup"]', function (event) { event.stopImmediatePropagation(); var self = $(this); var checked = self.prop('checked'); that[checked ? 'checkGroup' : 'uncheckGroup']($(this).closest('tr').data('group-index')); }); } initBodyCaller = false; this.updateSelected(); }; BootstrapTable.prototype.updateSelected = function () { if (!initBodyCaller) { _updateSelected.apply(this, Array.prototype.slice.apply(arguments)); if ((this.options.groupBy) && (this.options.groupByField !== '')) { this.$selectGroup.forEach(function (item) { var checkGroup = item.item.filter(':enabled').length === item.item.filter(':enabled').filter(':checked').length; item.group.prop('checked', checkGroup); }); } } }; BootstrapTable.prototype.getGroupSelections = function (index) { var that = this; return $.grep(this.data, function (row) { return (row[that.header.stateField] && (row._data['parent-index'] === index)); }); }; BootstrapTable.prototype.checkGroup = function (index) { this.checkGroup_(index, true); }; BootstrapTable.prototype.uncheckGroup = function (index) { this.checkGroup_(index, false); }; BootstrapTable.prototype.checkGroup_ = function (index, checked) { var rows; var filter = function() { return ($(this).closest('tr').data('parent-index') === index); }; if (!checked) { rows = this.getGroupSelections(index); } this.$selectItem.filter(filter).prop('checked', checked); this.updateRows(); this.updateSelected(); if (checked) { rows = this.getGroupSelections(index); } this.trigger(checked ? 'check-all' : 'uncheck-all', rows); }; }(jQuery);