Browse Source

add alternative group-by extension

y.slobodnuk 10 years ago
parent
commit
8a5088fd13

+ 24 - 0
src/extensions/group-by-v2/README.md

@@ -0,0 +1,24 @@
+# Table group-by-v2
+
+Use Plugin: [bootstrap-table-group-by-v2](https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/group-by-v2) </br>
+You must include the bootstrap-table-group-by.css file in order to get the appropriate style
+
+## Usage
+
+```html
+<script src="extensions/group-by-v2/bootstrap-table-group-by.js"></script>
+```
+
+## Options
+
+### groupBy
+
+* type: Boolean
+* description: Set true to group the data by the field passed.
+* default: `false`
+
+### groupByField
+
+* type: String
+* description: Set the fields name that you want to group the data.
+* default: ``

+ 7 - 0
src/extensions/group-by-v2/bootstrap-table-group-by.css

@@ -0,0 +1,7 @@
+.bootstrap-table .table > tbody > tr.groupBy {
+    cursor: pointer;
+}
+
+.bootstrap-table .table > tbody > tr.groupBy.expanded {
+
+}

+ 218 - 0
src/extensions/group-by-v2/bootstrap-table-group-by.js

@@ -0,0 +1,218 @@
+/**
+ * @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++;
+                    }
+                }
+            });
+
+            tableGroups.forEach(function(item){
+                var html = [];
+
+                html.push(sprintf('<tr class="info groupBy expanded" data-group-index="%s">', item.id));
+
+                if (checkBox) {
+                    html.push('<td class="bs-checkbox">',
+                        '<input name="btSelectGroup" type="checkbox" />',
+                        '</td>'
+                    );
+                }
+
+                html.push('<td',
+                    sprintf(' colspan="%s"', visibleColumns),
+                    '>', item.name, '</td>'
+                );
+
+                html.push('</tr>');
+
+                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);