UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

533 lines (525 loc) • 22.7 kB
/** * DevExtreme (cjs/__internal/grids/tree_list/selection/m_selection.js) * Version: 23.2.6 * Build date: Wed May 01 2024 * * Copyright (c) 2012 - 2024 Developer Express Inc. ALL RIGHTS RESERVED * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/ */ "use strict"; var _renderer = _interopRequireDefault(require("../../../../core/renderer")); var _common = require("../../../../core/utils/common"); var _extend = require("../../../../core/utils/extend"); var _type = require("../../../../core/utils/type"); var _m_selection = require("../../../grids/grid_core/selection/m_selection"); var _m_core = _interopRequireDefault(require("../m_core")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj } } function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass) } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function(o, p) { o.__proto__ = p; return o }; return _setPrototypeOf(o, p) } const TREELIST_SELECT_ALL_CLASS = "dx-treelist-select-all"; const SELECT_CHECKBOX_CLASS = "dx-select-checkbox"; const nodeExists = function(array, currentKey) { return !!array.filter(key => key === currentKey).length }; const data = Base => function(_dataSelectionExtende) { _inheritsLoose(DataSelectionTreeListExtender, _dataSelectionExtende); function DataSelectionTreeListExtender() { return _dataSelectionExtende.apply(this, arguments) || this } var _proto = DataSelectionTreeListExtender.prototype; _proto._handleDataChanged = function(e) { const isRecursiveSelection = this._selectionController.isRecursiveSelection(); if (isRecursiveSelection && (!e || "updateSelectionState" !== e.changeType)) { this._selectionController.updateSelectionState({ selectedItemKeys: this.option("selectedRowKeys") }) } _dataSelectionExtende.prototype._handleDataChanged.apply(this, arguments) }; _proto.loadDescendants = function() { const that = this; const d = _dataSelectionExtende.prototype.loadDescendants.apply(that, arguments); const isRecursiveSelection = this._selectionController.isRecursiveSelection(); if (isRecursiveSelection) { d.done(() => { this._selectionController.updateSelectionState({ selectedItemKeys: that.option("selectedRowKeys") }) }) } return d }; return DataSelectionTreeListExtender }((0, _m_selection.dataSelectionExtenderMixin)(Base)); const selection = Base => function(_Base) { _inheritsLoose(SelectionControllerTreeListExtender, _Base); function SelectionControllerTreeListExtender() { var _this; _this = _Base.apply(this, arguments) || this; _this._updateSelectColumn = _common.noop; return _this } var _proto2 = SelectionControllerTreeListExtender.prototype; _proto2.init = function() { _Base.prototype.init.apply(this, arguments); this._selectionStateByKey = {} }; _proto2._getSelectionConfig = function() { const config = _Base.prototype._getSelectionConfig.apply(this, arguments); const { plainItems: plainItems } = config; config.plainItems = cached => { let result; if (cached) { result = this._dataController.getCachedStoreData() } result || (result = plainItems.apply(this, arguments).map(item => item.data)); return result || [] }; config.isItemSelected = item => { const key = this._dataController.keyOf(item); return this.isRowSelected(key) }; config.isSelectableItem = item => !!item; config.getItemData = item => item; config.allowLoadByRange = void 0; return config }; _proto2.renderSelectCheckBoxContainer = function($container, model) { const rowsView = this.component.getView("rowsView"); const $checkbox = rowsView._renderSelectCheckBox($container, { value: model.row.isSelected, row: model.row, column: model.column }); rowsView._attachCheckBoxClickEvent($checkbox) }; _proto2._getSelectAllNodeKeys = function() { const { component: component } = this; const root = component.getRootNode(); const cache = {}; const keys = []; const isRecursiveSelection = this.isRecursiveSelection(); root && _m_core.default.foreachNodes(root.children, node => { if (void 0 !== node.key && (node.visible || isRecursiveSelection)) { keys.push(node.key) } if (!node.visible) { return true } return isRecursiveSelection ? false : component.isRowExpanded(node.key, cache) }); return keys }; _proto2.isSelectAll = function() { const selectedRowKeys = this.option("selectedRowKeys") || []; if (0 === selectedRowKeys.length) { return false } const { component: component } = this; const visibleKeys = this._getSelectAllNodeKeys(); const isRecursiveSelection = this.isRecursiveSelection(); let hasIndeterminateState = false; const selectedVisibleKeys = visibleKeys.filter(key => { const isRowSelected = component.isRowSelected(key, isRecursiveSelection); if (void 0 === isRowSelected) { hasIndeterminateState = true } return isRowSelected }); if (!selectedVisibleKeys.length) { return hasIndeterminateState ? void 0 : false } if (selectedVisibleKeys.length === visibleKeys.length) { return true } return }; _proto2.selectAll = function() { const visibleKeys = this._getSelectAllNodeKeys().filter(key => !this.isRowSelected(key)); this.focusedItemIndex(-1); return this.selectRows(visibleKeys, true) }; _proto2.deselectAll = function() { const visibleKeys = this._getSelectAllNodeKeys(); this.focusedItemIndex(-1); return this.deselectRows(visibleKeys) }; _proto2.selectedItemKeys = function(value, preserve, isDeselect, isSelectAll) { const that = this; const selectedRowKeys = that.option("selectedRowKeys"); const isRecursiveSelection = this.isRecursiveSelection(); const normalizedArgs = isRecursiveSelection && that._normalizeSelectionArgs({ keys: (0, _type.isDefined)(value) ? value : [] }, preserve, !isDeselect); if (normalizedArgs && !(0, _common.equalByValue)(normalizedArgs.selectedRowKeys, selectedRowKeys)) { that._isSelectionNormalizing = true; return _Base.prototype.selectedItemKeys.call(this, normalizedArgs.selectedRowKeys, false, false, false).always(() => { that._isSelectionNormalizing = false }).done(items => { normalizedArgs.selectedRowsData = items; that._fireSelectionChanged(normalizedArgs) }) } return _Base.prototype.selectedItemKeys.call(this, value, preserve, isDeselect, isSelectAll) }; _proto2.changeItemSelection = function(itemIndex, keyboardKeys) { const isRecursiveSelection = this.isRecursiveSelection(); const callBase = _Base.prototype.changeItemSelection.bind(this); if (isRecursiveSelection && !keyboardKeys.shift) { const key = this._dataController.getKeyByRowIndex(itemIndex); return this.selectedItemKeys(key, true, this.isRowSelected(key)).done(() => { this.isRowSelected(key) && callBase(itemIndex, keyboardKeys, true) }) } return _Base.prototype.changeItemSelection.apply(this, arguments) }; _proto2._updateParentSelectionState = function(node, isSelected) { const that = this; let state = isSelected; const parentNode = node.parent; if (parentNode) { if (parentNode.children.length > 1) { if (false === isSelected) { const hasSelectedState = parentNode.children.some(childNode => that._selectionStateByKey[childNode.key]); state = hasSelectedState ? void 0 : false } else if (true === isSelected) { const hasNonSelectedState = parentNode.children.some(childNode => !that._selectionStateByKey[childNode.key]); state = hasNonSelectedState ? void 0 : true } } this._selectionStateByKey[parentNode.key] = state; if (parentNode.parent && parentNode.parent.level >= 0) { this._updateParentSelectionState(parentNode, state) } } }; _proto2._updateChildrenSelectionState = function(node, isSelected) { const that = this; const { children: children } = node; children && children.forEach(childNode => { that._selectionStateByKey[childNode.key] = isSelected; if (childNode.children.length > 0) { that._updateChildrenSelectionState(childNode, isSelected) } }) }; _proto2._updateSelectionStateCore = function(keys, isSelected) { const dataController = this._dataController; for (let i = 0; i < keys.length; i++) { this._selectionStateByKey[keys[i]] = isSelected; const node = dataController.getNodeByKey(keys[i]); if (node) { this._updateParentSelectionState(node, isSelected); this._updateChildrenSelectionState(node, isSelected) } } }; _proto2._getSelectedParentKeys = function(key, selectedItemKeys, useCash) { let selectedParentNode; const node = this._dataController.getNodeByKey(key); let parentNode = node && node.parent; let result = []; while (parentNode && parentNode.level >= 0) { result.unshift(parentNode.key); const isSelected = useCash ? !nodeExists(selectedItemKeys, parentNode.key) && this.isRowSelected(parentNode.key) : selectedItemKeys.indexOf(parentNode.key) >= 0; if (isSelected) { selectedParentNode = parentNode; result = this._getSelectedParentKeys(selectedParentNode.key, selectedItemKeys, useCash).concat(result); break } else if (useCash) { break } parentNode = parentNode.parent } return selectedParentNode && result || [] }; _proto2._getSelectedChildKeys = function(key, keysToIgnore) { const childKeys = []; const node = this._dataController.getNodeByKey(key); node && _m_core.default.foreachNodes(node.children, childNode => { const ignoreKeyIndex = keysToIgnore.indexOf(childNode.key); if (ignoreKeyIndex < 0) { childKeys.push(childNode.key) } return ignoreKeyIndex > 0 || ignoreKeyIndex < 0 && void 0 === this._selectionStateByKey[childNode.key] }); return childKeys }; _proto2._normalizeParentKeys = function(key, args) { const that = this; let keysToIgnore = [key]; const parentNodeKeys = that._getSelectedParentKeys(key, args.selectedRowKeys); if (parentNodeKeys.length) { keysToIgnore = keysToIgnore.concat(parentNodeKeys); keysToIgnore.forEach(key => { const index = args.selectedRowKeys.indexOf(key); if (index >= 0) { args.selectedRowKeys.splice(index, 1) } }); const childKeys = that._getSelectedChildKeys(parentNodeKeys[0], keysToIgnore); args.selectedRowKeys = args.selectedRowKeys.concat(childKeys) } }; _proto2._normalizeChildrenKeys = function(key, args) { const node = this._dataController.getNodeByKey(key); node && node.children.forEach(childNode => { const index = args.selectedRowKeys.indexOf(childNode.key); if (index >= 0) { args.selectedRowKeys.splice(index, 1) } this._normalizeChildrenKeys(childNode.key, args) }) }; _proto2._normalizeSelectedRowKeysCore = function(keys, args, preserve, isSelect) { const that = this; keys.forEach(key => { if (preserve && that.isRowSelected(key) === isSelect) { return } that._normalizeChildrenKeys(key, args); const index = args.selectedRowKeys.indexOf(key); if (isSelect) { if (index < 0) { args.selectedRowKeys.push(key) } args.currentSelectedRowKeys.push(key) } else { if (index >= 0) { args.selectedRowKeys.splice(index, 1) } args.currentDeselectedRowKeys.push(key); that._normalizeParentKeys(key, args) } }) }; _proto2._normalizeSelectionArgs = function(args, preserve, isSelect) { let result; const keys = Array.isArray(args.keys) ? args.keys : [args.keys]; const selectedRowKeys = this.option("selectedRowKeys") || []; if (keys.length) { result = { currentSelectedRowKeys: [], currentDeselectedRowKeys: [], selectedRowKeys: preserve ? selectedRowKeys.slice(0) : [] }; this._normalizeSelectedRowKeysCore(keys, result, preserve, isSelect) } return result }; _proto2._updateSelectedItems = function(args) { this.updateSelectionState(args); _Base.prototype._updateSelectedItems.call(this, args) }; _proto2._fireSelectionChanged = function() { if (!this._isSelectionNormalizing) { _Base.prototype._fireSelectionChanged.apply(this, arguments) } }; _proto2._isModeLeavesOnly = function(mode) { return "leavesOnly" === mode }; _proto2._removeDuplicatedKeys = function(keys) { const result = []; const processedKeys = {}; keys.forEach(key => { if (!processedKeys[key]) { processedKeys[key] = true; result.push(key) } }); return result }; _proto2._getAllChildKeys = function(key) { const childKeys = []; const node = this._dataController.getNodeByKey(key); node && _m_core.default.foreachNodes(node.children, childNode => { childKeys.push(childNode.key) }, true); return childKeys }; _proto2._getAllSelectedRowKeys = function(keys) { let result = []; keys.forEach(key => { const parentKeys = this._getSelectedParentKeys(key, [], true); const childKeys = this._getAllChildKeys(key); result.push.apply(result, parentKeys.concat([key], childKeys)) }); result = this._removeDuplicatedKeys(result); return result }; _proto2._getParentSelectedRowKeys = function(keys) { const that = this; const result = []; keys.forEach(key => { const parentKeys = that._getSelectedParentKeys(key, keys); !parentKeys.length && result.push(key) }); return result }; _proto2._getLeafSelectedRowKeys = function(keys) { const result = []; const dataController = this._dataController; keys.forEach(key => { const node = dataController.getNodeByKey(key); node && !node.hasChildren && result.push(key) }); return result }; _proto2.isRecursiveSelection = function() { const selectionMode = this.option("selection.mode"); const isRecursive = this.option("selection.recursive"); return "multiple" === selectionMode && isRecursive }; _proto2.updateSelectionState = function(options) { const removedItemKeys = options.removedItemKeys || []; const selectedItemKeys = options.selectedItemKeys || []; if (this.isRecursiveSelection()) { this._updateSelectionStateCore(removedItemKeys, false); this._updateSelectionStateCore(selectedItemKeys, true) } }; _proto2.isRowSelected = function(key, isRecursiveSelection) { const result = _Base.prototype.isRowSelected.apply(this, arguments); isRecursiveSelection = null !== isRecursiveSelection && void 0 !== isRecursiveSelection ? isRecursiveSelection : this.isRecursiveSelection(); if (!result && isRecursiveSelection) { if (key in this._selectionStateByKey) { return this._selectionStateByKey[key] } return false } return result }; _proto2.getSelectedRowKeys = function(mode) { const that = this; if (!that._dataController) { return [] } let selectedRowKeys = _Base.prototype.getSelectedRowKeys.apply(that, arguments); if (mode) { if (this.isRecursiveSelection()) { selectedRowKeys = this._getAllSelectedRowKeys(selectedRowKeys) } if ("all" !== mode) { if ("excludeRecursive" === mode) { selectedRowKeys = that._getParentSelectedRowKeys(selectedRowKeys) } else if (that._isModeLeavesOnly(mode)) { selectedRowKeys = that._getLeafSelectedRowKeys(selectedRowKeys) } } } return selectedRowKeys }; _proto2.getSelectedRowsData = function(mode) { const dataController = this._dataController; const selectedKeys = this.getSelectedRowKeys(mode) || []; const selectedRowsData = []; selectedKeys.forEach(key => { const node = dataController.getNodeByKey(key); node && selectedRowsData.push(node.data) }); return selectedRowsData }; _proto2.refresh = function() { this._selectionStateByKey = {}; return _Base.prototype.refresh.apply(this, arguments) }; return SelectionControllerTreeListExtender }(Base); const columnHeadersView = Base => function(_columnHeadersSelecti) { _inheritsLoose(ColumnHeaderViewSelectionTreeListExtender, _columnHeadersSelecti); function ColumnHeaderViewSelectionTreeListExtender() { return _columnHeadersSelecti.apply(this, arguments) || this } var _proto3 = ColumnHeaderViewSelectionTreeListExtender.prototype; _proto3._processTemplate = function(template, options) { const that = this; let resultTemplate; const renderingTemplate = _columnHeadersSelecti.prototype._processTemplate.call(this, template, options); const firstDataColumnIndex = that._columnsController.getFirstDataColumnIndex(); if (renderingTemplate && "header" === options.rowType && options.column.index === firstDataColumnIndex) { resultTemplate = { render(options) { if ("multiple" === that.option("selection.mode")) { that.renderSelectAll(options.container, options.model) } renderingTemplate.render(options) } } } else { resultTemplate = renderingTemplate } return resultTemplate }; _proto3.renderSelectAll = function($cell, options) { $cell.addClass("dx-treelist-select-all"); this._renderSelectAllCheckBox($cell) }; _proto3._isSortableElement = function($target) { return _columnHeadersSelecti.prototype._isSortableElement.call(this, $target) && !$target.closest(".".concat("dx-select-checkbox")).length }; return ColumnHeaderViewSelectionTreeListExtender }((0, _m_selection.columnHeadersSelectionExtenderMixin)(Base)); const rowsView = Base => function(_rowsViewSelectionExt) { _inheritsLoose(RowsViewSelectionTreeListExtender, _rowsViewSelectionExt); function RowsViewSelectionTreeListExtender() { return _rowsViewSelectionExt.apply(this, arguments) || this } var _proto4 = RowsViewSelectionTreeListExtender.prototype; _proto4._renderIcons = function($iconContainer, options) { _rowsViewSelectionExt.prototype._renderIcons.apply(this, arguments); if (!options.row.isNewRow && "multiple" === this.option("selection.mode")) { this._selectionController.renderSelectCheckBoxContainer($iconContainer, options) } return $iconContainer }; _proto4._rowClick = function(e) { const $targetElement = (0, _renderer.default)(e.event.target); if (this.isExpandIcon($targetElement)) { _rowsViewSelectionExt.prototype._rowClickForTreeList.apply(this, arguments) } else { _rowsViewSelectionExt.prototype._rowClick.apply(this, arguments) } }; return RowsViewSelectionTreeListExtender }((0, _m_selection.rowsViewSelectionExtenderMixin)(Base)); _m_core.default.registerModule("selection", (0, _extend.extend)(true, {}, _m_selection.selectionModule, { defaultOptions: () => (0, _extend.extend)(true, _m_selection.selectionModule.defaultOptions(), { selection: { showCheckBoxesMode: "always", recursive: false } }), extenders: { controllers: { data: data, selection: selection }, views: { columnHeadersView: columnHeadersView, rowsView: rowsView } } }));