UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

682 lines (679 loc) • 29.2 kB
/** * DevExtreme (ui/collection/ui.collection_widget.edit.js) * Version: 18.2.18 * Build date: Tue Oct 18 2022 * * Copyright (c) 2012 - 2022 Developer Express Inc. ALL RIGHTS RESERVED * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/ */ "use strict"; var _renderer = require("../../core/renderer"); var _renderer2 = _interopRequireDefault(_renderer); var _events_engine = require("../../events/core/events_engine"); var _events_engine2 = _interopRequireDefault(_events_engine); var _uiCollection_widget = require("./ui.collection_widget.base"); var _uiCollection_widget2 = _interopRequireDefault(_uiCollection_widget); var _ui = require("../widget/ui.errors"); var _ui2 = _interopRequireDefault(_ui); var _extend = require("../../core/utils/extend"); var _iterator = require("../../core/utils/iterator"); var _common = require("../../core/utils/common"); var _type = require("../../core/utils/type"); var _uiCollection_widgetEditStrategy = require("./ui.collection_widget.edit.strategy.plain"); var _uiCollection_widgetEditStrategy2 = _interopRequireDefault(_uiCollection_widgetEditStrategy); var _data = require("../../core/utils/data"); var _data_source = require("../../data/data_source/data_source"); var _selection = require("../selection/selection"); var _selection2 = _interopRequireDefault(_selection); var _deferred = require("../../core/utils/deferred"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj } } function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i] } return arr2 } else { return Array.from(arr) } } var ITEM_DELETING_DATA_KEY = "dxItemDeleting"; var NOT_EXISTING_INDEX = -1; var indexExists = function(index) { return index !== NOT_EXISTING_INDEX }; var CollectionWidget = _uiCollection_widget2.default.inherit({ _setOptionsByReference: function() { this.callBase(); (0, _extend.extend)(this._optionsByReference, { selectedItem: true }) }, _getDefaultOptions: function() { return (0, _extend.extend)(this.callBase(), { selectionMode: "none", selectionRequired: false, selectionByClick: true, selectedItems: [], selectedItemKeys: [], maxFilterLengthInRequest: 1500, keyExpr: null, selectedIndex: NOT_EXISTING_INDEX, selectedItem: null, onSelectionChanged: null, onItemReordered: null, onItemDeleting: null, onItemDeleted: null }) }, ctor: function(element, options) { this._userOptions = options || {}; this.callBase(element, options) }, _init: function() { this._initEditStrategy(); this.callBase(); this._initKeyGetter(); this._initSelectionModule(); if ("multi" === this.option("selectionMode")) { this._showDeprecatedSelectionMode() } }, _initKeyGetter: function() { this._keyGetter = (0, _data.compileGetter)(this.option("keyExpr")) }, _getKeysByItems: function(selectedItems) { return this._editStrategy.getKeysByItems(selectedItems) }, _getItemsByKeys: function(selectedItemKeys, selectedItems) { return this._editStrategy.getItemsByKeys(selectedItemKeys, selectedItems) }, _getKeyByIndex: function(index) { return this._editStrategy.getKeyByIndex(index) }, _getIndexByKey: function(key) { return this._editStrategy.getIndexByKey(key) }, _getIndexByItemData: function(itemData) { return this._editStrategy.getIndexByItemData(itemData) }, _isKeySpecified: function() { return !!(this._dataSource && this._dataSource.key()) }, _getCombinedFilter: function() { return this._dataSource && this._dataSource.filter() }, key: function() { if (this.option("keyExpr")) { return this.option("keyExpr") } return this._dataSource && this._dataSource.key() }, keyOf: function(item) { var key = item; var store = this._dataSource && this._dataSource.store(); if (this.option("keyExpr")) { key = this._keyGetter(item) } else { if (store) { key = store.keyOf(item) } } return key }, _initSelectionModule: function() { var that = this, itemsGetter = that._editStrategy.itemsGetter; this._selection = new _selection2.default({ mode: this.option("selectionMode"), maxFilterLengthInRequest: this.option("maxFilterLengthInRequest"), equalByReference: !this._isKeySpecified(), onSelectionChanged: function(args) { if (args.addedItemKeys.length || args.removedItemKeys.length) { that.option("selectedItems", that._getItemsByKeys(args.selectedItemKeys, args.selectedItems)); that._updateSelectedItems(args) } }, filter: that._getCombinedFilter.bind(that), totalCount: function() { var items = that.option("items"); var dataSource = that._dataSource; return dataSource && dataSource.totalCount() >= 0 ? dataSource.totalCount() : items.length }, key: that.key.bind(that), keyOf: that.keyOf.bind(that), load: function(options) { if (that._dataSource) { var loadOptions = that._dataSource.loadOptions(); options.customQueryParams = loadOptions.customQueryParams; options.userData = that._dataSource._userData } var store = that._dataSource && that._dataSource.store(); if (store) { return store.load(options).done(function(loadResult) { if (that._disposed) { return } var items = (0, _data_source.normalizeLoadResult)(loadResult).data; that._dataSource._applyMapFunction(items) }) } else { return (new _deferred.Deferred).resolve(this.plainItems()) } }, dataFields: function() { return that._dataSource && that._dataSource.select() }, plainItems: itemsGetter.bind(that._editStrategy) }) }, _initEditStrategy: function() { var Strategy = _uiCollection_widgetEditStrategy2.default; this._editStrategy = new Strategy(this) }, _getSelectedItemIndices: function(keys) { var that = this, indices = []; keys = keys || this._selection.getSelectedItemKeys(); that._editStrategy.beginCache(); (0, _iterator.each)(keys, function(_, key) { var selectedIndex = that._getIndexByKey(key); if (indexExists(selectedIndex)) { indices.push(selectedIndex) } }); that._editStrategy.endCache(); return indices }, _initMarkup: function() { var _this = this; this._rendering = true; if (!this._dataSource || !this._dataSource.isLoading()) { this._syncSelectionOptions().done(function() { return _this._normalizeSelectedItems() }) } this.callBase(); var selectedItemIndices = this._getSelectedItemIndices(); this._renderSelection(selectedItemIndices, []) }, _render: function() { this.callBase(); this._rendering = false }, _fireContentReadyAction: function() { this._rendering = false; this._rendered = true; this.callBase.apply(this, arguments) }, _syncSelectionOptions: function(byOption) { byOption = byOption || this._chooseSelectOption(); var selectedItem = void 0; var selectedIndex = void 0; var selectedItemKeys = void 0; var selectedItems = void 0; switch (byOption) { case "selectedIndex": selectedItem = this._editStrategy.getItemDataByIndex(this.option("selectedIndex")); if ((0, _type.isDefined)(selectedItem)) { this._setOptionSilent("selectedItems", [selectedItem]); this._setOptionSilent("selectedItem", selectedItem); this._setOptionSilent("selectedItemKeys", this._editStrategy.getKeysByItems([selectedItem])) } else { this._setOptionSilent("selectedItems", []); this._setOptionSilent("selectedItemKeys", []); this._setOptionSilent("selectedItem", null) } break; case "selectedItems": selectedItems = this.option("selectedItems") || []; selectedIndex = this._editStrategy.getIndexByItemData(selectedItems[0]); if (this.option("selectionRequired") && !indexExists(selectedIndex)) { return this._syncSelectionOptions("selectedIndex") } this._setOptionSilent("selectedItem", selectedItems[0]); this._setOptionSilent("selectedIndex", selectedIndex); this._setOptionSilent("selectedItemKeys", this._editStrategy.getKeysByItems(selectedItems)); break; case "selectedItem": selectedItem = this.option("selectedItem"); selectedIndex = this._editStrategy.getIndexByItemData(selectedItem); if (this.option("selectionRequired") && !indexExists(selectedIndex)) { return this._syncSelectionOptions("selectedIndex") } if ((0, _type.isDefined)(selectedItem)) { this._setOptionSilent("selectedItems", [selectedItem]); this._setOptionSilent("selectedIndex", selectedIndex); this._setOptionSilent("selectedItemKeys", this._editStrategy.getKeysByItems([selectedItem])) } else { this._setOptionSilent("selectedItems", []); this._setOptionSilent("selectedItemKeys", []); this._setOptionSilent("selectedIndex", NOT_EXISTING_INDEX) } break; case "selectedItemKeys": selectedItemKeys = this.option("selectedItemKeys"); if (this.option("selectionRequired")) { var selectedItemIndex = this._getIndexByKey(selectedItemKeys[0]); if (!indexExists(selectedItemIndex)) { return this._syncSelectionOptions("selectedIndex") } } return this._selection.setSelection(selectedItemKeys) } return (new _deferred.Deferred).resolve().promise() }, _chooseSelectOption: function() { var optionName = "selectedIndex"; var isOptionDefined = function(optionName) { var optionValue = this.option(optionName), length = (0, _type.isDefined)(optionValue) && optionValue.length; return length || optionName in this._userOptions }.bind(this); if (isOptionDefined("selectedItems")) { optionName = "selectedItems" } else { if (isOptionDefined("selectedItem")) { optionName = "selectedItem" } else { if (isOptionDefined("selectedItemKeys")) { optionName = "selectedItemKeys" } } } return optionName }, _compareKeys: function(oldKeys, newKeys) { if (oldKeys.length !== newKeys.length) { return false } for (var i = 0; i < newKeys.length; i++) { if (oldKeys[i] !== newKeys[i]) { return false } } return true }, _normalizeSelectedItems: function() { if ("none" === this.option("selectionMode")) { this._setOptionSilent("selectedItems", []); this._syncSelectionOptions("selectedItems") } else { if ("single" === this.option("selectionMode")) { var newSelection = this.option("selectedItems"); if (newSelection.length > 1 || !newSelection.length && this.option("selectionRequired") && this.option("items") && this.option("items").length) { var currentSelection = this._selection.getSelectedItems(); var normalizedSelection = void 0 === newSelection[0] ? currentSelection[0] : newSelection[0]; if (void 0 === normalizedSelection) { normalizedSelection = this._editStrategy.itemsGetter()[0] } if (this.option("grouped") && normalizedSelection && normalizedSelection.items) { normalizedSelection.items = [normalizedSelection.items[0]] } this._selection.setSelection(this._getKeysByItems([normalizedSelection])); this._setOptionSilent("selectedItems", [normalizedSelection]); return this._syncSelectionOptions("selectedItems") } else { this._selection.setSelection(this._getKeysByItems(newSelection)) } } else { var newKeys = this._getKeysByItems(this.option("selectedItems")); var oldKeys = this._selection.getSelectedItemKeys(); if (!this._compareKeys(oldKeys, newKeys)) { this._selection.setSelection(newKeys) } } } return (new _deferred.Deferred).resolve().promise() }, _renderSelection: _common.noop, _itemClickHandler: function(e) { this._createAction(function(e) { this._itemSelectHandler(e.event) }.bind(this), { validatingTargetName: "itemElement" })({ itemElement: (0, _renderer2.default)(e.currentTarget), event: e }); this.callBase.apply(this, arguments) }, _itemSelectHandler: function(e) { if (!this.option("selectionByClick")) { return } var $itemElement = e.currentTarget; if (this.isItemSelected($itemElement)) { this.unselectItem(e.currentTarget) } else { this.selectItem(e.currentTarget) } }, _selectedItemElement: function(index) { return this._itemElements().eq(index) }, _postprocessRenderItem: function(args) { if ("none" !== this.option("selectionMode")) { var $itemElement = (0, _renderer2.default)(args.itemElement), normalizedItemIndex = this._editStrategy.getNormalizedIndex($itemElement), isItemSelected = this._isItemSelected(normalizedItemIndex); this._processSelectableItem($itemElement, isItemSelected) } }, _processSelectableItem: function($itemElement, isSelected) { $itemElement.toggleClass(this._selectedItemClass(), isSelected); this._setAriaSelected($itemElement, String(isSelected)) }, _updateSelectedItems: function(args) { var that = this, addedItemKeys = args.addedItemKeys, removedItemKeys = args.removedItemKeys; if (that._rendered && (addedItemKeys.length || removedItemKeys.length)) { var selectionChangePromise = that._selectionChangePromise; if (!that._rendering) { var addedSelection = []; var normalizedIndex = void 0; var removedSelection = []; that._editStrategy.beginCache(); for (var i = 0; i < addedItemKeys.length; i++) { normalizedIndex = that._getIndexByKey(addedItemKeys[i]); addedSelection.push(normalizedIndex); that._addSelection(normalizedIndex) } for (var _i = 0; _i < removedItemKeys.length; _i++) { normalizedIndex = that._getIndexByKey(removedItemKeys[_i]); removedSelection.push(normalizedIndex); that._removeSelection(normalizedIndex) } that._editStrategy.endCache(); that._updateSelection(addedSelection, removedSelection) }(0, _deferred.when)(selectionChangePromise).done(function() { that._fireSelectionChangeEvent(args.addedItems, args.removedItems) }) } }, _fireSelectionChangeEvent: function(addedItems, removedItems) { this._createActionByOption("onSelectionChanged", { excludeValidators: ["disabled", "readOnly"] })({ addedItems: addedItems, removedItems: removedItems }) }, _updateSelection: function() { this._renderSelection.apply(this, arguments) }, _setAriaSelected: function($target, value) { this.setAria("selected", value, $target) }, _removeSelection: function(normalizedIndex) { var $itemElement = this._editStrategy.getItemElement(normalizedIndex); if (indexExists(normalizedIndex)) { this._processSelectableItem($itemElement, false); _events_engine2.default.triggerHandler($itemElement, "stateChanged", false) } }, _showDeprecatedSelectionMode: function() { _ui2.default.log("W0001", this.NAME, "selectionMode: 'multi'", "16.1", "Use selectionMode: 'multiple' instead"); this.option("selectionMode", "multiple") }, _addSelection: function(normalizedIndex) { var $itemElement = this._editStrategy.getItemElement(normalizedIndex); if (indexExists(normalizedIndex)) { this._processSelectableItem($itemElement, true); _events_engine2.default.triggerHandler($itemElement, "stateChanged", true) } }, _isItemSelected: function(index) { var key = this._getKeyByIndex(index); return this._selection.isItemSelected(key) }, _optionChanged: function(args) { var _this2 = this; switch (args.name) { case "selectionMode": if ("multi" === args.value) { this._showDeprecatedSelectionMode() } else { this._invalidate() } break; case "dataSource": if (!args.value || Array.isArray(args.value) && !args.value.length) { this.option("selectedItemKeys", []) } this.callBase(args); break; case "selectedIndex": case "selectedItem": case "selectedItems": case "selectedItemKeys": this._syncSelectionOptions(args.name).done(function() { return _this2._normalizeSelectedItems() }); break; case "keyExpr": this._initKeyGetter(); break; case "selectionRequired": this._normalizeSelectedItems(); break; case "selectionByClick": case "onSelectionChanged": case "onItemDeleting": case "onItemDeleted": case "onItemReordered": case "maxFilterLengthInRequest": break; default: this.callBase(args) } }, _clearSelectedItems: function() { this._setOptionSilent("selectedItems", []); this._syncSelectionOptions("selectedItems") }, _waitDeletingPrepare: function($itemElement) { if ($itemElement.data(ITEM_DELETING_DATA_KEY)) { return (new _deferred.Deferred).resolve().promise() } $itemElement.data(ITEM_DELETING_DATA_KEY, true); var deferred = new _deferred.Deferred, deletingActionArgs = { cancel: false }, deletePromise = this._itemEventHandler($itemElement, "onItemDeleting", deletingActionArgs, { excludeValidators: ["disabled", "readOnly"] }); (0, _deferred.when)(deletePromise).always(function(value) { var deletePromiseExists = !deletePromise, deletePromiseResolved = !deletePromiseExists && "resolved" === deletePromise.state(), argumentsSpecified = !!arguments.length, shouldDelete = deletePromiseExists || deletePromiseResolved && !argumentsSpecified || deletePromiseResolved && value; (0, _deferred.when)((0, _deferred.fromPromise)(deletingActionArgs.cancel)).always(function() { $itemElement.data(ITEM_DELETING_DATA_KEY, false) }).done(function(cancel) { shouldDelete && !cancel ? deferred.resolve() : deferred.reject() }).fail(deferred.reject) }.bind(this)); return deferred.promise() }, _deleteItemFromDS: function($item) { if (!this._dataSource) { return (new _deferred.Deferred).resolve().promise() } var deferred = new _deferred.Deferred, disabledState = this.option("disabled"), dataStore = this._dataSource.store(); this.option("disabled", true); if (!dataStore.remove) { throw _ui2.default.Error("E1011") } dataStore.remove(dataStore.keyOf(this._getItemData($item))).done(function(key) { if (void 0 !== key) { deferred.resolve() } else { deferred.reject() } }).fail(function() { deferred.reject() }); deferred.always(function() { this.option("disabled", disabledState) }.bind(this)); return deferred }, _tryRefreshLastPage: function() { var deferred = new _deferred.Deferred; if (this._isLastPage() || this.option("grouped")) { deferred.resolve() } else { this._refreshLastPage().done(function() { deferred.resolve() }) } return deferred.promise() }, _refreshLastPage: function() { this._expectLastItemLoading(); return this._dataSource.load() }, _updateSelectionAfterDelete: function(index) { var key = this._getKeyByIndex(index); this._selection.deselect([key]) }, _updateIndicesAfterIndex: function(index) { var itemElements = this._itemElements(); for (var i = index + 1; i < itemElements.length; i++) { (0, _renderer2.default)(itemElements[i]).data(this._itemIndexKey(), i - 1) } }, _simulateOptionChange: function(optionName) { var optionValue = this.option(optionName); if (optionValue instanceof _data_source.DataSource) { return } this._optionChangedAction({ name: optionName, fullName: optionName, value: optionValue }) }, isItemSelected: function(itemElement) { return this._isItemSelected(this._editStrategy.getNormalizedIndex(itemElement)) }, selectItem: function(itemElement) { if ("none" === this.option("selectionMode")) { return } var itemIndex = this._editStrategy.getNormalizedIndex(itemElement); if (!indexExists(itemIndex)) { return } var key = this._getKeyByIndex(itemIndex); if (this._selection.isItemSelected(key)) { return } if ("single" === this.option("selectionMode")) { this._selection.setSelection([key]) } else { var selectedItemKeys = this.option("selectedItemKeys") || []; this._selection.setSelection([].concat(_toConsumableArray(selectedItemKeys), [key])) } }, unselectItem: function(itemElement) { var itemIndex = this._editStrategy.getNormalizedIndex(itemElement); if (!indexExists(itemIndex)) { return } var selectedItemKeys = this._selection.getSelectedItemKeys(); if (this.option("selectionRequired") && selectedItemKeys.length <= 1) { return } var key = this._getKeyByIndex(itemIndex); if (!this._selection.isItemSelected(key)) { return } this._selection.deselect([key]) }, _deleteItemElementByIndex: function(index) { this._updateSelectionAfterDelete(index); this._updateIndicesAfterIndex(index); this._editStrategy.deleteItemAtIndex(index) }, _afterItemElementDeleted: function($item, deletedActionArgs) { var changingOption = this._dataSource ? "dataSource" : "items"; this._simulateOptionChange(changingOption); this._itemEventHandler($item, "onItemDeleted", deletedActionArgs, { beforeExecute: function() { $item.remove() }, excludeValidators: ["disabled", "readOnly"] }); this._renderEmptyMessage() }, deleteItem: function(itemElement) { var that = this, deferred = new _deferred.Deferred, $item = this._editStrategy.getItemElement(itemElement), index = this._editStrategy.getNormalizedIndex(itemElement), itemResponseWaitClass = this._itemResponseWaitClass(); if (indexExists(index)) { this._waitDeletingPrepare($item).done(function() { $item.addClass(itemResponseWaitClass); var deletedActionArgs = that._extendActionArgs($item); that._deleteItemFromDS($item).done(function() { that._deleteItemElementByIndex(index); that._afterItemElementDeleted($item, deletedActionArgs); that._tryRefreshLastPage().done(function() { deferred.resolveWith(that) }) }).fail(function() { $item.removeClass(itemResponseWaitClass); deferred.rejectWith(that) }) }).fail(function() { deferred.rejectWith(that) }) } else { deferred.rejectWith(that) } return deferred.promise() }, reorderItem: function(itemElement, toItemElement) { var deferred = new _deferred.Deferred, that = this, strategy = this._editStrategy, $movingItem = strategy.getItemElement(itemElement), $destinationItem = strategy.getItemElement(toItemElement), movingIndex = strategy.getNormalizedIndex(itemElement), destinationIndex = strategy.getNormalizedIndex(toItemElement), changingOption = this._dataSource ? "dataSource" : "items"; var canMoveItems = indexExists(movingIndex) && indexExists(destinationIndex) && movingIndex !== destinationIndex; if (canMoveItems) { deferred.resolveWith(this) } else { deferred.rejectWith(this) } return deferred.promise().done(function() { $destinationItem[strategy.itemPlacementFunc(movingIndex, destinationIndex)]($movingItem); strategy.moveItemAtIndexToIndex(movingIndex, destinationIndex); this._updateIndicesAfterIndex(movingIndex); that.option("selectedItems", that._getItemsByKeys(that._selection.getSelectedItemKeys(), that._selection.getSelectedItems())); if ("items" === changingOption) { that._simulateOptionChange(changingOption) } that._itemEventHandler($movingItem, "onItemReordered", { fromIndex: strategy.getIndex(movingIndex), toIndex: strategy.getIndex(destinationIndex) }, { excludeValidators: ["disabled", "readOnly"] }) }) } }); module.exports = CollectionWidget;