| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230 |
- /**
- * @author: Yura Knoxville
- * @version: v1.1.0
- */
- let initBodyCaller
- let tableGroups
- // it only does '%s', and return '' when arguments are undefined
- const sprintf = function (str) {
- const args = arguments
- let flag = true
- let i = 1
- str = str.replace(/%s/g, () => {
- const arg = args[i++]
- if (typeof arg === 'undefined') {
- flag = false
- return ''
- }
- return arg
- })
- return flag ? str : ''
- }
- const groupBy = (array, f) => {
- const groups = {}
- array.forEach(o => {
- const group = f(o)
- groups[group] = groups[group] || []
- groups[group].push(o)
- })
- return groups
- }
- $.extend($.fn.bootstrapTable.defaults, {
- groupBy: false,
- groupByField: '',
- groupByFormatter: undefined
- })
- const Utils = $.fn.bootstrapTable.utils
- const BootstrapTable = $.fn.bootstrapTable.Constructor
- const _initSort = BootstrapTable.prototype.initSort
- const _initBody = BootstrapTable.prototype.initBody
- const _updateSelected = BootstrapTable.prototype.updateSelected
- BootstrapTable.prototype.initSort = function (...args) {
- _initSort.apply(this, Array.prototype.slice.apply(args))
- const that = this
- tableGroups = []
- if ((this.options.groupBy) && (this.options.groupByField !== '')) {
- if ((this.options.sortName !== this.options.groupByField)) {
- if (this.options.customSort) {
- Utils.calculateObjectValue(this.options, this.options.customSort, [
- this.options.sortName,
- this.options.sortOrder,
- this.data
- ])
- } 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 groups = groupBy(that.data, item => [item[that.options.groupByField]])
- let index = 0
- $.each(groups, (key, value) => {
- tableGroups.push({
- id: index,
- name: key,
- data: value
- })
- value.forEach(item => {
- if (!item._data) {
- item._data = {}
- }
- item._data['parent-index'] = index
- })
- index++
- })
- }
- }
- BootstrapTable.prototype.initBody = function (...args) {
- initBodyCaller = true
- _initBody.apply(this, Array.prototype.slice.apply(args))
- if ((this.options.groupBy) && (this.options.groupByField !== '')) {
- const that = this
- let checkBox = false
- let visibleColumns = 0
- this.columns.forEach(column => {
- if (column.checkbox) {
- checkBox = true
- } else {
- if (column.visible) {
- visibleColumns += 1
- }
- }
- })
- if (this.options.detailView && !this.options.cardView) {
- visibleColumns += 1
- }
- tableGroups.forEach(item => {
- const html = []
- html.push(sprintf('<tr class="info groupBy expanded" data-group-index="%s">', item.id))
- if (that.options.detailView && !that.options.cardView) {
- html.push('<td class="detail"></td>')
- }
- if (checkBox) {
- html.push('<td class="bs-checkbox">',
- '<input name="btSelectGroup" type="checkbox" />',
- '</td>'
- )
- }
- let formattedValue = item.name
- if (typeof(that.options.groupByFormatter) === 'function') {
- formattedValue = that.options.groupByFormatter(item.name, item.id, item.data)
- }
- html.push('<td',
- sprintf(' colspan="%s"', visibleColumns),
- '>', formattedValue, '</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 () {
- const 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()
- const self = $(this)
- const checked = self.prop('checked')
- that[checked ? 'checkGroup' : 'uncheckGroup']($(this).closest('tr').data('group-index'))
- })
- }
- initBodyCaller = false
- this.updateSelected()
- }
- BootstrapTable.prototype.updateSelected = function (...args) {
- if (!initBodyCaller) {
- _updateSelected.apply(this, Array.prototype.slice.apply(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.group.prop('checked', checkGroup)
- })
- }
- }
- }
- BootstrapTable.prototype.getGroupSelections = function (index) {
- const that = this
- return this.data.filter(row => 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) {
- let rows
- const 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)
- }
|