@huntianning/components
Version:
Custom components for HTN
240 lines (238 loc) • 8.13 kB
JavaScript
import Vue from 'vue'
import { uniq } from './utils.js'
/* eslint-disable */
export default (options) => {
const plugin = {
selectModel: 'all', // all | page
selectionRows: [],
keepAllSelected: false,
excludeKeys: [],
includeKeys: [],
state: Vue.observable({
checkedAll: false,
indeterminate: false
}),
init (options) {
this.options = Object.assign({
grid: null,
selectionRows: null,
selectionInfo: null,
change: null
}, options)
this.grid = this.options.grid
if (this.options.selectionInfo) {
this.keepAllSelected = !!this.options.selectionInfo.keepAllSelected
this.excludeKeys = this.options.selectionInfo.excludeKeys || []
this.includeKeys = this.options.selectionInfo.includeKeys || []
}
this.selectionRows = this.options.selectionRows
this.handleSelectionChange = (selection) => {
if (this.disabledSelectionChange) {
return
}
this.checkExcludeKeys(selection)
}
this.handleLoad = () => {
this.syncCheckedState()
this.checkAllCheckboxState()
Vue.nextTick(() => {
this.disabledSelectionChange = false
})
}
this.handleReload = () => {
this.excludeKeys = []
this.includeKeys = []
this.state.checkedAll = this.keepAllSelected
this.state.indeterminate = false
this.selectionRows = []
if (this.selectModel === 'all') {
this.options.change && this.options.change({
selectModel: this.selectModel,
keepAllSelected: this.keepAllSelected,
excludeKeys: this.excludeKeys,
includeKeys: this.includeKeys
})
} else {
this.options.change && this.options.change({
selectModel: this.selectModel,
selectionRows: this.selectionRows
})
}
}
this.handleQuery = () => {
this.disabledSelectionChange = true
}
this.grid.$on('selection-change', this.handleSelectionChange)
this.grid.$on('load', this.handleLoad)
this.grid.$on('_reload', this.handleReload)
this.grid.$on('_query', this.handleQuery)
},
setSelectModel (selectModel) {
if (!['page', 'all'].includes(selectModel)) {
throw new Error('不正确的选择模式' + selectModel)
}
this.selectModel = selectModel
},
selectAll () {
this.excludeKeys = []
this.includeKeys = []
this.state.checkedAll = true
this.state.indeterminate = false
this.keepAllSelected = true
this.grid.selectAll()
if (this.selectModel === 'all') {
this.options.change && this.options.change({
selectModel: this.selectModel,
keepAllSelected: this.keepAllSelected,
excludeKeys: this.excludeKeys,
includeKeys: this.includeKeys
})
} else {
this.options.change && this.options.change({
selectModel: this.selectModel,
selectionRows: this.selectionRows
})
}
},
deselectAll () {
this.excludeKeys = []
this.includeKeys = []
this.state.checkedAll = false
this.state.indeterminate = false
this.keepAllSelected = false
this.grid.deselectAll()
if (this.selectModel === 'all') {
this.options.change && this.options.change({
selectModel: this.selectModel,
keepAllSelected: this.keepAllSelected,
excludeKeys: this.excludeKeys,
includeKeys: this.includeKeys
})
} else {
this.options.change && this.options.change({
selectModel: this.selectModel,
selectionRows: this.selectionRows
})
}
},
handleCheckAllChange (checked) {
if (checked) {
this.selectAll()
} else {
this.deselectAll()
}
},
syncCheckedState () {
if (this.selectModel === 'all') {
if (this.keepAllSelected) {
const excludeKeys = this.excludeKeys.map(v => v[this.grid.rowKey])
this.grid.tableData.forEach(row => {
if (excludeKeys.includes(row[this.grid.rowKey])) {
this.grid.toggleRowSelection(row, false)
} else {
this.grid.toggleRowSelection(row, true)
}
})
} else {
const includeKeys = this.includeKeys.map(v => v[this.grid.rowKey])
this.grid.tableData.forEach(row => {
if (includeKeys.includes(row[this.grid.rowKey])) {
this.grid.toggleRowSelection(row, true)
} else {
this.grid.toggleRowSelection(row, false)
}
})
}
} else {
const includeKeys = (this.selectionRows || []).map(v => v[this.grid.rowKey])
this.grid.tableData.forEach(row => {
if (includeKeys.includes(row[this.grid.rowKey])) {
this.grid.toggleRowSelection(row, true)
} else {
this.grid.toggleRowSelection(row, false)
}
})
}
},
checkExcludeKeys (selection) {
if (this.selectModel === 'all') {
if (this.keepAllSelected) {
const currExcludeKeys = []
const selectionMap = selection.reduce((rs, v) => {
rs[v[this.grid.rowKey]] = v
return rs
}, {})
const prevExcludeKeys = this.excludeKeys.filter(v => !selectionMap[v[this.grid.rowKey]])
this.grid.tableData.forEach(v => {
if (!selectionMap[v[this.grid.rowKey]]) {
currExcludeKeys.push(v)
}
})
this.excludeKeys = uniq([].concat(currExcludeKeys, prevExcludeKeys), this.grid.rowKey)
} else {
const dataMap = this.grid.tableData.reduce((rs, v) => {
rs[v[this.grid.rowKey]] = v
return rs
}, {})
const currIncludeKeys = this.includeKeys.filter(v => !dataMap[v[this.grid.rowKey]])
this.includeKeys = uniq([].concat(currIncludeKeys, selection), this.grid.rowKey)
}
this.options.change && this.options.change({
selectModel: this.selectModel,
keepAllSelected: this.keepAllSelected,
excludeKeys: this.excludeKeys,
includeKeys: this.includeKeys
})
} else {
this.selectionRows = selection
this.options.change && this.options.change({
selectModel: this.selectModel,
selectionRows: this.selectionRows
})
}
this.checkAllCheckboxState()
},
checkAllCheckboxState () {
if (this.selectModel === 'all') {
if (this.keepAllSelected) {
this.state.checkedAll = this.excludeKeys.length === 0
this.state.indeterminate = !this.state.checkedAll && this.excludeKeys.length > 0 && this.excludeKeys.length < this.grid.tableTotal
} else {
this.state.checkedAll = this.includeKeys.length >= this.grid.tableTotal
this.state.indeterminate = !this.state.checkedAll && this.includeKeys.length > 0
}
} else {
this.state.checkedAll = this.selectionRows.length >= this.grid.tableData.length
this.state.indeterminate = !this.state.checkedAll && this.selectionRows.length > 0
}
},
render (h) {
return h('div', {
class: 'ui-grid-plugin-select-all'
}, [
h('ui-checkbox', {
props: {
value: this.state.checkedAll,
indeterminate: this.state.indeterminate
},
on: {
input: (checked) => {
this.state.checkedAll = checked
this.state.indeterminate = false
this.handleCheckAllChange(checked)
}
}
})
])
},
destroy () {
this.grid.$off('selection-change', this.handleSelectionChange)
this.grid.$off('load', this.handleLoad)
this.grid.$off('_reload', this.handleReload)
this.grid.$off('_query', this.handleQuery)
}
}
plugin.init(options)
return plugin
}
/* eslint-enable */