Browse Source

added the ability to select multiple fields for grouping (#4860)

* added the ability to select multiple fields for grouping

* linting
Dustin Utecht 5 years ago
parent
commit
fed0b753b9

+ 4 - 2
site/docs/extensions/group-by-v2.md

@@ -35,11 +35,13 @@ toc: true
 
 - **attribute:** `data-group-by-field`
 
-- **type:** `String`
+- **type:** `String|Array`
 
 - **Detail:**
 
-   Set the field name that you want to group the data.
+   Set the field name(s) that you want to group the data.  
+   For a single field use a `String` e.g. `shape`.   
+   For a multiple fields use a `Array` e.g. `["shape", "color"]`.   
 
 - **Default:** `''`
 

+ 40 - 12
src/extensions/group-by-v2/bootstrap-table-group-by.js

@@ -24,14 +24,14 @@ const sprintf = function (str) {
 }
 
 const groupBy = (array, f) => {
-  const groups = {}
+  const tmpGroups = {}
   array.forEach(o => {
-    const group = f(o)
-    groups[group] = groups[group] || []
-    groups[group].push(o)
+    const groups = f(o)
+    tmpGroups[groups] = tmpGroups[groups] || []
+    tmpGroups[groups].push(o)
   })
 
-  return groups
+  return tmpGroups
 }
 
 $.extend($.fn.bootstrapTable.defaults, {
@@ -63,14 +63,31 @@ BootstrapTable.prototype.initSort = function (...args) {
         ])
       } else {
         this.data.sort((a, b) => {
-          a = a[that.options.groupByField].toString()
-          b = b[that.options.groupByField].toString()
-          return a.localeCompare(b, undefined, { numeric: true })
+          const groupByFields = this.getGroupByFields()
+          const fieldValuesA = []
+          const fieldValuesB = []
+
+          $.each(groupByFields, (i, field) => {
+            fieldValuesA.push(a[field])
+            fieldValuesB.push(b[field])
+          })
+
+          a = fieldValuesA.join()
+          b = fieldValuesB.join()
+          return a.localeCompare(b, undefined, {numeric: true})
         })
       }
     }
 
-    const groups = groupBy(that.data, item => [item[that.options.groupByField]])
+    const groups = groupBy(that.data, (item) => {
+      const groupByFields = this.getGroupByFields()
+      const groupValues = []
+      $.each(groupByFields, (i, field) => {
+        groupValues.push(item[field])
+      })
+
+      return groupValues.join(', ')
+    })
 
     let index = 0
     $.each(groups, (key, value) => {
@@ -133,7 +150,7 @@ BootstrapTable.prototype.initBody = function (...args) {
         )
       }
       let formattedValue = item.name
-      if (typeof(that.options.groupByFormatter) === 'function') {
+      if (typeof (that.options.groupByFormatter) === 'function') {
         formattedValue = that.options.groupByFormatter(item.name, item.id, item.data)
       }
       html.push('<td',
@@ -154,7 +171,7 @@ BootstrapTable.prototype.initBody = function (...args) {
         group: self,
         item: that.$selectItem.filter(function () {
           return ($(this).closest('tr').data('parent-index') ===
-                      self.closest('tr').data('group-index'))
+            self.closest('tr').data('group-index'))
         })
       })
     })
@@ -186,7 +203,7 @@ BootstrapTable.prototype.updateSelected = function (...args) {
     if ((this.options.groupBy) && (this.options.groupByField !== '')) {
       this.$selectGroup.forEach(item => {
         const checkGroup = item.item.filter(':enabled').length ===
-                      item.item.filter(':enabled').filter(':checked').length
+          item.item.filter(':enabled').filter(':checked').length
 
         item.group.prop('checked', checkGroup)
       })
@@ -227,3 +244,14 @@ BootstrapTable.prototype.checkGroup_ = function (index, checked) {
   }
   this.trigger(checked ? 'check-all' : 'uncheck-all', rows)
 }
+
+
+BootstrapTable.prototype.getGroupByFields = function () {
+  let groupByFields = this.options.groupByField
+  if (!$.isArray(this.options.groupByField))
+  {
+    groupByFields = [this.options.groupByField]
+  }
+
+  return groupByFields
+}