| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297 |
- /**
- * @author: Yura Knoxville
- * @version: v1.1.0
- */
- let initBodyCaller
- const groupBy = (array, f) => {
- const tmpGroups = {}
- array.forEach(o => {
- const groups = f(o)
- tmpGroups[groups] = tmpGroups[groups] || []
- tmpGroups[groups].push(o)
- })
- return tmpGroups
- }
- $.extend($.fn.bootstrapTable.defaults.icons, {
- collapseGroup: {
- bootstrap3: 'glyphicon-chevron-up',
- materialize: 'arrow_drop_down'
- }[$.fn.bootstrapTable.theme] || 'fa-angle-up',
- expandGroup: {
- bootstrap3: 'glyphicon-chevron-down',
- materialize: 'arrow_drop_up'
- }[$.fn.bootstrapTable.theme] || 'fa-angle-down'
- })
- $.extend($.fn.bootstrapTable.defaults, {
- groupBy: false,
- groupByField: '',
- groupByFormatter: undefined,
- groupByToggle: false,
- groupByShowToggleIcon: false,
- groupByCollapsedGroups: []
- })
- 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
- 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) => {
- 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) => {
- const groupByFields = this.getGroupByFields()
- const groupValues = []
- $.each(groupByFields, (i, field) => {
- groupValues.push(item[field])
- })
- return groupValues.join(', ')
- })
- let index = 0
- $.each(groups, (key, value) => {
- this.tableGroups.push({
- id: index,
- name: key,
- data: value
- })
- value.forEach(item => {
- if (!item._data) {
- item._data = {}
- }
- if (this.isCollapsed(key, value)) {
- item._class = 'hidden'
- }
- 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
- }
- this.tableGroups.forEach(item => {
- const html = []
- html.push(Utils.sprintf('<tr class="info groupBy %s" data-group-index="%s">', this.options.groupByToggle ? 'expanded' : '', 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',
- Utils.sprintf(' colspan="%s"', visibleColumns),
- '>', formattedValue
- )
- let icon = this.options.icons.collapseGroup
- if (this.isCollapsed(item.name, item.data)) {
- icon = this.options.icons.expandGroup
- }
- if (this.options.groupByToggle && this.options.groupByShowToggleIcon) {
- html.push(`<span class="float-right ${this.options.iconsPrefix} ${icon}"></span>`)
- }
- html.push('</td></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'))
- })
- })
- })
- if (this.options.groupByToggle) {
- this.$container.off('click', '.groupBy')
- .on('click', '.groupBy', function () {
- $(this).toggleClass('expanded collapsed')
- $(this).find('span').toggleClass(`${that.options.icons.collapseGroup} ${that.options.icons.expandGroup}`)
- 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.checkGroup = function (index) {
- this.checkGroup_(index, true)
- }
- BootstrapTable.prototype.uncheckGroup = function (index) {
- this.checkGroup_(index, false)
- }
- BootstrapTable.prototype.isCollapsed = function (groupKey, items) {
- if (this.options.groupByCollapsedGroups) {
- const collapsedGroups = Utils.calculateObjectValue(this, this.options.groupByCollapsedGroups, [groupKey, items], true)
- if ($.inArray(groupKey, collapsedGroups) > -1) {
- return true
- }
- }
- return false
- }
- BootstrapTable.prototype.checkGroup_ = function (index, checked) {
- const rowsBefore = this.getSelections()
- let rows
- const filter = function () {
- return ($(this).closest('tr').data('parent-index') === index)
- }
- this.$selectItem.filter(filter).prop('checked', checked)
- this.updateRows()
- this.updateSelected()
- const rowsAfter = this.getSelections()
- if (checked) {
- this.trigger('check-all', rowsAfter, rowsBefore)
- return
- }
- this.trigger('uncheck-all', rowsAfter, rowsBefore)
- }
- BootstrapTable.prototype.getGroupByFields = function () {
- let groupByFields = this.options.groupByField
- if (!$.isArray(this.options.groupByField)) {
- groupByFields = [this.options.groupByField]
- }
- return groupByFields
- }
- $.BootstrapTable = class extends $.BootstrapTable {
- scrollTo (params) {
- if (this.options.groupBy) {
- let options = {unit: 'px', value: 0}
- if (typeof params === 'object') {
- options = Object.assign(options, params)
- }
- if (options.unit === 'rows') {
- let scrollTo = 0
- this.$body.find(`> tr:not(.groupBy):lt(${options.value})`).each((i, el) => {
- scrollTo += $(el).outerHeight(true)
- })
- const $targetColumn = this.$body.find(`> tr:not(.groupBy):eq(${options.value})`)
- $targetColumn.prevAll('.groupBy').each((i, el) => {
- scrollTo += $(el).outerHeight(true)
- })
- this.$tableBody.scrollTop(scrollTo)
- return
- }
- }
- super.scrollTo(params)
- }
- }
|