UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

885 lines (874 loc) • 39.7 kB
/** * DevExtreme (cjs/__internal/grids/grid_core/focus/m_focus.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"; Object.defineProperty(exports, "__esModule", { value: true }); exports.focusModule = exports.FocusController = void 0; var _renderer = _interopRequireDefault(require("../../../../core/renderer")); var _common = require("../../../../core/utils/common"); var _deferred = require("../../../../core/utils/deferred"); var _iterator = require("../../../../core/utils/iterator"); var _type = require("../../../../core/utils/type"); var _m_editing_utils = require("../editing/m_editing_utils"); var _m_modules = _interopRequireDefault(require("../m_modules")); var _m_utils = _interopRequireDefault(require("../m_utils")); var _m_focus_utils = require("./m_focus_utils"); 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 ROW_FOCUSED_CLASS = "dx-row-focused"; const FOCUSED_ROW_SELECTOR = ".dx-row.".concat("dx-row-focused"); const TABLE_POSTFIX_CLASS = "table"; const CELL_FOCUS_DISABLED_CLASS = "dx-cell-focus-disabled"; let FocusController = function(_core$ViewController) { _inheritsLoose(FocusController, _core$ViewController); function FocusController() { return _core$ViewController.apply(this, arguments) || this } var _proto = FocusController.prototype; _proto.getKeyboardController = function() { return this.getController("keyboardNavigation") }; _proto.getDataController = function() { return this.getController("data") }; _proto.init = function() { this.component._optionsByReference.focusedRowKey = true }; _proto.optionChanged = function(args) { const { name: name, value: value, previousValue: previousValue } = args; switch (name) { case "focusedRowIndex": this._focusRowByIndex(value); this.getKeyboardController()._fireFocusedRowChanged(); args.handled = true; break; case "focusedRowKey": if (Array.isArray(value) && JSON.stringify(value) === JSON.stringify(previousValue)) { return } this._focusRowByKey(value); this.getKeyboardController()._fireFocusedRowChanged(); args.handled = true; break; case "focusedColumnIndex": case "focusedRowEnabled": case "autoNavigateToFocusedRow": args.handled = true; break; default: _core$ViewController.prototype.optionChanged.call(this, args) } }; _proto.publicMethods = function() { return ["navigateToRow", "isRowFocused"] }; _proto.isAutoNavigateToFocusedRow = function() { return "infinite" !== this.option("scrolling.mode") && this.option("autoNavigateToFocusedRow") }; _proto._focusRowByIndex = function(index, operationTypes) { if (!this.option("focusedRowEnabled")) { return } index = void 0 !== index ? index : this.option("focusedRowIndex"); if (index < 0) { if (this.isAutoNavigateToFocusedRow()) { this._resetFocusedRow() } } else { this._focusRowByIndexCore(index, operationTypes) } }; _proto._focusRowByIndexCore = function(index, operationTypes) { const pageSize = this.getDataController().pageSize(); const setKeyByIndex = () => { if (this._isValidFocusedRowIndex(index)) { let rowIndex = index - this.getDataController().getRowIndexOffset(true); if (!operationTypes || operationTypes.paging && !operationTypes.filtering) { const lastItemIndex = this.getDataController()._getLastItemIndex(); rowIndex = Math.min(rowIndex, lastItemIndex) } const focusedRowKey = this.getDataController().getKeyByRowIndex(rowIndex, true); if ((0, _type.isDefined)(focusedRowKey) && !this.isRowFocused(focusedRowKey)) { this.option("focusedRowKey", focusedRowKey) } } }; if (pageSize >= 0) { if (!this._isLocalRowIndex(index)) { const pageIndex = Math.floor(index / this.getDataController().pageSize()); (0, _deferred.when)(this.getDataController().pageIndex(pageIndex), this.getDataController().waitReady()).done(() => { setKeyByIndex() }) } else { setKeyByIndex() } } }; _proto._isLocalRowIndex = function(index) { const isVirtualScrolling = this.getKeyboardController()._isVirtualScrolling(); if (isVirtualScrolling) { const pageIndex = Math.floor(index / this.getDataController().pageSize()); const virtualItems = this.getDataController().virtualItemsCount(); const virtualItemsBegin = virtualItems ? virtualItems.begin : -1; const visibleRowsCount = this.getDataController().getVisibleRows().length + this.getDataController().getRowIndexOffset(); const visiblePagesCount = Math.ceil(visibleRowsCount / this.getDataController().pageSize()); return virtualItemsBegin <= index && visiblePagesCount > pageIndex } return true }; _proto._setFocusedRowKeyByIndex = function(index) { if (this._isValidFocusedRowIndex(index)) { const rowIndex = Math.min(index - this.getDataController().getRowIndexOffset(), this.getDataController().items().length - 1); const focusedRowKey = this.getDataController().getKeyByRowIndex(rowIndex); if ((0, _type.isDefined)(focusedRowKey) && !this.isRowFocused(focusedRowKey)) { this.option("focusedRowKey", focusedRowKey) } } }; _proto._focusRowByKey = function(key) { if (!(0, _type.isDefined)(key)) { this._resetFocusedRow() } else { this._navigateToRow(key, true) } }; _proto._resetFocusedRow = function() { const focusedRowKey = this.option("focusedRowKey"); const isFocusedRowKeyDefined = (0, _type.isDefined)(focusedRowKey); if (!isFocusedRowKeyDefined && this.option("focusedRowIndex") < 0) { return } if (isFocusedRowKeyDefined) { this.option("focusedRowKey", null) } this.getKeyboardController().setFocusedRowIndex(-1); this.option("focusedRowIndex", -1); this.getDataController().updateItems({ changeType: "updateFocusedRow", focusedRowKey: null }); this.getKeyboardController()._fireFocusedRowChanged() }; _proto._isValidFocusedRowIndex = function(rowIndex) { const row = this.getDataController().getVisibleRows()[rowIndex]; return !row || "data" === row.rowType || "group" === row.rowType }; _proto.navigateToRow = function(key) { if (!this.isAutoNavigateToFocusedRow()) { this.option("focusedRowIndex", -1) } return this._navigateToRow(key) }; _proto._navigateToRow = function(key, needFocusRow) { const that = this; const isAutoNavigate = that.isAutoNavigateToFocusedRow(); const d = new _deferred.Deferred; if (void 0 === key || !this.getDataController().dataSource()) { return d.reject().promise() } const rowIndexByKey = that.getFocusedRowIndexByKey(key); if (!isAutoNavigate && needFocusRow || rowIndexByKey >= 0) { that._navigateTo(key, d, needFocusRow) } else { this.getDataController().getPageIndexByKey(key).done(pageIndex => { if (pageIndex < 0) { d.resolve(-1); return } if (pageIndex === this.getDataController().pageIndex()) { this.getDataController().reload().done(() => { if (that.isRowFocused(key) && this.getDataController().getRowIndexByKey(key) >= 0) { d.resolve(that.getFocusedRowIndexByKey(key)) } else { that._navigateTo(key, d, needFocusRow) } }).fail(d.reject) } else { this.getDataController().pageIndex(pageIndex).done(() => { that._navigateTo(key, d, needFocusRow) }).fail(d.reject) } }).fail(d.reject) } return d.promise() }; _proto._navigateTo = function(key, deferred, needFocusRow) { const visibleRowIndex = this.getDataController().getRowIndexByKey(key); const isVirtualRowRenderingMode = _m_utils.default.isVirtualRowRendering(this); const isAutoNavigate = this.isAutoNavigateToFocusedRow(); if (isAutoNavigate && isVirtualRowRenderingMode && visibleRowIndex < 0) { this._navigateToVirtualRow(key, deferred, needFocusRow) } else { this._navigateToVisibleRow(key, deferred, needFocusRow) } }; _proto._navigateToVisibleRow = function(key, deferred, needFocusRow) { if (needFocusRow) { this._triggerUpdateFocusedRow(key, deferred) } else { const focusedRowIndex = this.getFocusedRowIndexByKey(key); this.getView("rowsView").scrollToRowElement(key, deferred).done(() => { deferred.resolve(focusedRowIndex) }) } }; _proto._navigateToVirtualRow = function(key, deferred, needFocusRow) { const rowsScrollController = this.getDataController()._rowsScrollController; const rowIndex = _m_utils.default.getIndexByKey(key, this.getDataController().items(true)); const scrollable = this.getView("rowsView").getScrollable(); if (rowsScrollController && scrollable && rowIndex >= 0) { const focusedRowIndex = rowIndex + this.getDataController().getRowIndexOffset(true); const offset = rowsScrollController.getItemOffset(focusedRowIndex); const triggerUpdateFocusedRow = () => { if (this.getDataController().totalCount() && !this.getDataController().items().length) { return } this.component.off("contentReady", triggerUpdateFocusedRow); if (needFocusRow) { this._triggerUpdateFocusedRow(key, deferred) } else { deferred.resolve(focusedRowIndex) } }; this.component.on("contentReady", triggerUpdateFocusedRow); this.getView("rowsView").scrollTopPosition(offset) } else { deferred.resolve(-1) } }; _proto._triggerUpdateFocusedRow = function(key, deferred) { const focusedRowIndex = this.getFocusedRowIndexByKey(key); if (this._isValidFocusedRowIndex(focusedRowIndex)) { let d; if (this.option("focusedRowEnabled")) { this.getDataController().updateItems({ changeType: "updateFocusedRow", focusedRowKey: key }) } else { d = this.getView("rowsView").scrollToRowElement(key) }(0, _deferred.when)(d).done(() => { this.getKeyboardController().setFocusedRowIndex(focusedRowIndex); deferred && deferred.resolve(focusedRowIndex) }) } else { deferred && deferred.resolve(-1) } }; _proto.getFocusedRowIndexByKey = function(key) { const loadedRowIndex = this.getDataController().getRowIndexByKey(key, true); return loadedRowIndex >= 0 ? loadedRowIndex + this.getDataController().getRowIndexOffset(true) : -1 }; _proto._focusRowByKeyOrIndex = function() { const focusedRowKey = this.option("focusedRowKey"); let currentFocusedRowIndex = this.option("focusedRowIndex"); if ((0, _type.isDefined)(focusedRowKey)) { const visibleRowIndex = this.getDataController().getRowIndexByKey(focusedRowKey); if (visibleRowIndex >= 0) { if (this.getKeyboardController()._isVirtualScrolling()) { currentFocusedRowIndex = visibleRowIndex + this.getDataController().getRowIndexOffset() } this.getKeyboardController().setFocusedRowIndex(currentFocusedRowIndex); this._triggerUpdateFocusedRow(focusedRowKey) } else { this._navigateToRow(focusedRowKey, true).done(focusedRowIndex => { if (currentFocusedRowIndex >= 0 && focusedRowIndex < 0) { this._focusRowByIndex() } else if (currentFocusedRowIndex < 0 && focusedRowIndex >= 0) { this.getKeyboardController().setFocusedRowIndex(focusedRowIndex) } }) } } else if (currentFocusedRowIndex >= 0) { this._focusRowByIndex(currentFocusedRowIndex) } }; _proto.isRowFocused = function(key) { const focusedRowKey = this.option("focusedRowKey"); if ((0, _type.isDefined)(focusedRowKey)) { return (0, _common.equalByValue)(key, this.option("focusedRowKey")) } return }; _proto.updateFocusedRow = function(e) { var _a; const that = this; const focusedRowIndex = null !== (_a = e.focusedRowIndex) && void 0 !== _a ? _a : that.getDataController().getRowIndexByKey(e.focusedRowKey); const rowsView = that.getView("rowsView"); let $tableElement; let $mainRow; (0, _iterator.each)(rowsView.getTableElements(), (index, element) => { const isMainTable = 0 === index; $tableElement = (0, _renderer.default)(element); that._clearPreviousFocusedRow($tableElement, focusedRowIndex); const $row = that._prepareFocusedRow({ changedItem: that.getDataController().getVisibleRows()[focusedRowIndex], $tableElement: $tableElement, focusedRowIndex: focusedRowIndex }); if (isMainTable) { $mainRow = $row } }); if (!e.preventScroll && $mainRow) { rowsView.scrollToElementVertically($mainRow) } }; _proto._clearPreviousFocusedRow = function($tableElement, focusedRowIndex) { const $prevRowFocusedElement = $tableElement.find(FOCUSED_ROW_SELECTOR).filter((_, focusedRow) => { const $focusedRowTable = (0, _renderer.default)(focusedRow).closest(".".concat(this.addWidgetPrefix("table"))); return $tableElement.is($focusedRowTable) }); $prevRowFocusedElement.removeClass("dx-row-focused").removeClass("dx-cell-focus-disabled").removeAttr("tabindex"); $prevRowFocusedElement.children("td").removeAttr("tabindex"); if (0 !== focusedRowIndex) { const $firstRow = (0, _renderer.default)(this.getView("rowsView").getRowElement(0)); $firstRow.removeClass("dx-cell-focus-disabled").removeAttr("tabIndex") } }; _proto._prepareFocusedRow = function(options) { let $row; const { changedItem: changedItem } = options; if (changedItem && ("data" === changedItem.rowType || "group" === changedItem.rowType)) { const { focusedRowIndex: focusedRowIndex } = options; const { $tableElement: $tableElement } = options; const tabIndex = this.option("tabindex") || 0; const rowsView = this.getView("rowsView"); $row = (0, _renderer.default)(rowsView._getRowElements($tableElement).eq(focusedRowIndex)); $row.addClass("dx-row-focused").attr("tabindex", tabIndex) } return $row }; return FocusController }(_m_modules.default.ViewController); exports.FocusController = FocusController; const keyboardNavigation = Base => function(_Base) { _inheritsLoose(FocusKeyboardNavigationExtender, _Base); function FocusKeyboardNavigationExtender() { return _Base.apply(this, arguments) || this } var _proto2 = FocusKeyboardNavigationExtender.prototype; _proto2.init = function() { const rowIndex = this.option("focusedRowIndex"); const columnIndex = this.option("focusedColumnIndex"); this.createAction("onFocusedRowChanging", { excludeValidators: ["disabled", "readOnly"] }); this.createAction("onFocusedRowChanged", { excludeValidators: ["disabled", "readOnly"] }); this.createAction("onFocusedCellChanging", { excludeValidators: ["disabled", "readOnly"] }); this.createAction("onFocusedCellChanged", { excludeValidators: ["disabled", "readOnly"] }); _Base.prototype.init.call(this); this.setRowFocusType(); this._focusedCellPosition = {}; if ((0, _type.isDefined)(rowIndex) && rowIndex >= 0) { this._focusedCellPosition.rowIndex = rowIndex } if ((0, _type.isDefined)(columnIndex) && columnIndex >= 0) { this._focusedCellPosition.columnIndex = columnIndex } }; _proto2.setFocusedRowIndex = function(rowIndex) { _Base.prototype.setFocusedRowIndex.call(this, rowIndex); this.option("focusedRowIndex", rowIndex) }; _proto2.setFocusedColumnIndex = function(columnIndex) { _Base.prototype.setFocusedColumnIndex.call(this, columnIndex); this.option("focusedColumnIndex", columnIndex) }; _proto2._escapeKeyHandler = function(eventArgs, isEditing) { if (isEditing || !this.option("focusedRowEnabled")) { return _Base.prototype._escapeKeyHandler.call(this, eventArgs, isEditing) } if (this.isCellFocusType()) { this.setRowFocusType(); this._focus(this._getCellElementFromTarget(eventArgs.originalEvent.target), true); return true } return false }; _proto2._updateFocusedCellPosition = function($cell, direction) { const position = _Base.prototype._updateFocusedCellPosition.call(this, $cell, direction); if (position && position.columnIndex >= 0) { this._fireFocusedCellChanged($cell) } return position }; return FocusKeyboardNavigationExtender }(Base); const editorFactory = Base => function(_Base2) { _inheritsLoose(FocusEditorFactoryExtender, _Base2); function FocusEditorFactoryExtender() { return _Base2.apply(this, arguments) || this } var _proto3 = FocusEditorFactoryExtender.prototype; _proto3.renderFocusOverlay = function($element, isHideBorder) { var _a; const focusedRowEnabled = this.option("focusedRowEnabled"); let $cell; if (!focusedRowEnabled || !(null === (_a = this._keyboardNavigationController) || void 0 === _a ? void 0 : _a.isRowFocusType()) || this._editingController.isEditing()) { _Base2.prototype.renderFocusOverlay.call(this, $element, isHideBorder) } else if (focusedRowEnabled) { const isRowElement = "row" === this._keyboardNavigationController._getElementType($element); if (isRowElement && !$element.hasClass("dx-row-focused")) { $cell = this._keyboardNavigationController.getFirstValidCellInRow($element); this._keyboardNavigationController.focus($cell) } } }; return FocusEditorFactoryExtender }(Base); const columns = Base => function(_Base3) { _inheritsLoose(FocusColumnsExtender, _Base3); function FocusColumnsExtender() { return _Base3.apply(this, arguments) || this } var _proto4 = FocusColumnsExtender.prototype; _proto4.getSortDataSourceParameters = function(_, sortByKey) { let result = _Base3.prototype.getSortDataSourceParameters.apply(this, arguments); const dataSource = this._dataController._dataSource; const store = this._dataController.store(); let key = store && store.key(); const remoteOperations = dataSource && dataSource.remoteOperations() || {}; const isLocalOperations = Object.keys(remoteOperations).every(operationName => !remoteOperations[operationName]); if (key && (this.option("focusedRowEnabled") && false !== this._focusController.isAutoNavigateToFocusedRow() || sortByKey)) { key = Array.isArray(key) ? key : [key]; const notSortedKeys = key.filter(key => !this.columnOption(key, "sortOrder")); if (notSortedKeys.length) { result = result || []; if (isLocalOperations) { result.push({ selector: dataSource.getDataIndexGetter(), desc: false }) } else { notSortedKeys.forEach(notSortedKey => result.push({ selector: notSortedKey, desc: false })) } } } return result }; return FocusColumnsExtender }(Base); const data = Base => function(_Base4) { _inheritsLoose(FocusDataControllerExtender, _Base4); function FocusDataControllerExtender() { return _Base4.apply(this, arguments) || this } var _proto5 = FocusDataControllerExtender.prototype; _proto5._applyChange = function(change) { if (change && "updateFocusedRow" === change.changeType) { return } return _Base4.prototype._applyChange.apply(this, arguments) }; _proto5._fireChanged = function(e) { _Base4.prototype._fireChanged.call(this, e); if (this.option("focusedRowEnabled") && this._dataSource) { const isPartialUpdate = "update" === e.changeType && e.repaintChangesOnly; const isPartialUpdateWithDeleting = isPartialUpdate && e.changeTypes && e.changeTypes.indexOf("remove") >= 0; if ("refresh" === e.changeType && e.items.length || isPartialUpdateWithDeleting) { this._updatePageIndexes(); this._updateFocusedRow(e) } else if ("append" === e.changeType || "prepend" === e.changeType) { this._updatePageIndexes() } else if ("update" === e.changeType && e.repaintChangesOnly) { this._updateFocusedRow(e) } } }; _proto5._updatePageIndexes = function() { const prevRenderingPageIndex = this._lastRenderingPageIndex || 0; const renderingPageIndex = this._rowsScrollController ? this._rowsScrollController.pageIndex() : 0; this._lastRenderingPageIndex = renderingPageIndex; this._isPagingByRendering = renderingPageIndex !== prevRenderingPageIndex }; _proto5.isPagingByRendering = function() { return this._isPagingByRendering }; _proto5._updateFocusedRow = function(e) { const operationTypes = e.operationTypes || {}; const { reload: reload, fullReload: fullReload, pageIndex: pageIndex, paging: paging } = operationTypes; const isVirtualScrolling = this._keyboardNavigationController._isVirtualScrolling(); const pagingWithoutVirtualScrolling = paging && !isVirtualScrolling; const focusedRowKey = this.option("focusedRowKey"); const isAutoNavigate = this._focusController.isAutoNavigateToFocusedRow(); const isReload = reload && false === pageIndex; if (isReload && !fullReload && (0, _type.isDefined)(focusedRowKey)) { this._focusController._navigateToRow(focusedRowKey, true).done(focusedRowIndex => { if (focusedRowIndex < 0) { this._focusController._focusRowByIndex(void 0, operationTypes) } }) } else if (pagingWithoutVirtualScrolling && isAutoNavigate) { const rowIndexByKey = this.getRowIndexByKey(focusedRowKey); const focusedRowIndex = this.option("focusedRowIndex"); const isValidRowIndexByKey = rowIndexByKey >= 0; const isValidFocusedRowIndex = focusedRowIndex >= 0; const isSameRowIndex = focusedRowIndex === rowIndexByKey; if (isValidFocusedRowIndex && (isSameRowIndex || !isValidRowIndexByKey)) { this._focusController._focusRowByIndex(focusedRowIndex, operationTypes) } } else if (pagingWithoutVirtualScrolling && !isAutoNavigate && this.getRowIndexByKey(focusedRowKey) < 0) { this.option("focusedRowIndex", -1) } else if (operationTypes.fullReload) { this._focusController._focusRowByKeyOrIndex() } }; _proto5.getPageIndexByKey = function(key) { const that = this; const d = new _deferred.Deferred; that.getGlobalRowIndexByKey(key).done(globalIndex => { d.resolve(globalIndex >= 0 ? Math.floor(globalIndex / that.pageSize()) : -1) }).fail(d.reject); return d.promise() }; _proto5.getGlobalRowIndexByKey = function(key) { if (this._dataSource.group()) { return this._calculateGlobalRowIndexByGroupedData(key) } return this._calculateGlobalRowIndexByFlatData(key) }; _proto5._calculateGlobalRowIndexByFlatData = function(key, groupFilter, useGroup) { const that = this; const deferred = new _deferred.Deferred; const dataSource = that._dataSource; if (Array.isArray(key) || (0, _m_editing_utils.isNewRowTempKey)(key)) { return deferred.resolve(-1).promise() } let filter = that._generateFilterByKey(key); dataSource.load({ filter: that._concatWithCombinedFilter(filter), skip: 0, take: 1 }).done(data => { if (data.length > 0) { filter = that._generateOperationFilterByKey(key, data[0], useGroup); dataSource.load({ filter: that._concatWithCombinedFilter(filter, groupFilter), skip: 0, take: 1, requireTotalCount: true }).done((_, extra) => { deferred.resolve(extra.totalCount) }) } else { deferred.resolve(-1) } }); return deferred.promise() }; _proto5._concatWithCombinedFilter = function(filter, groupFilter) { const combinedFilter = this.getCombinedFilter(); return _m_utils.default.combineFilters([filter, combinedFilter, groupFilter]) }; _proto5._generateBooleanFilter = function(selector, value, sortInfo) { const { desc: desc } = sortInfo; switch (true) { case false === value && desc: return [selector, "=", true]; case false === value && !desc: return [selector, "=", null]; case true === value && !desc: case !(0, _type.isBoolean)(value) && desc: return [selector, "<>", value]; default: return } }; _proto5._generateOperationFilterByKey = function(key, rowData, useGroup) { const that = this; const dateSerializationFormat = that.option("dateSerializationFormat"); const isRemoteFiltering = that._dataSource.remoteOperations().filtering; const isRemoteSorting = that._dataSource.remoteOperations().sorting; let filter = that._generateFilterByKey(key, "<"); let sort = that._columnsController.getSortDataSourceParameters(!isRemoteFiltering, true); if (useGroup) { const group = that._columnsController.getGroupDataSourceParameters(!isRemoteFiltering); if (group) { sort = sort ? group.concat(sort) : group } } if (sort) { sort.slice().reverse().forEach(sortInfo => { const { selector: selector, desc: desc, compare: compare } = sortInfo; const { getter: getter, rawValue: rawValue, safeValue: safeValue } = _m_focus_utils.UiGridCoreFocusUtils.getSortFilterValue(sortInfo, rowData, { isRemoteFiltering: isRemoteFiltering, dateSerializationFormat: dateSerializationFormat, getSelector: selector => that._columnsController.columnOption(selector, "selector") }); filter = [ [selector, "=", safeValue], "and", filter ]; if (null === rawValue || (0, _type.isBoolean)(rawValue)) { const booleanFilter = that._generateBooleanFilter(selector, safeValue, desc); if (booleanFilter) { filter = [booleanFilter, "or", filter] } } else { const filterOperation = desc ? ">" : "<"; let sortFilter; if (compare && !isRemoteSorting) { sortFilter = data => { if ("<" === filterOperation) { return compare(rawValue, getter(data)) >= 1 } return compare(rawValue, getter(data)) <= -1 } } else { sortFilter = [selector, filterOperation, safeValue]; if (!desc) { sortFilter = [sortFilter, "or", [selector, "=", null]] } } filter = [sortFilter, "or", filter] } }) } return filter }; _proto5._generateFilterByKey = function(key, operation) { const dataSourceKey = this._dataSource.key(); let filter = []; if (!operation) { operation = "=" } if (Array.isArray(dataSourceKey)) { for (let i = 0; i < dataSourceKey.length; ++i) { const keyPart = key[dataSourceKey[i]]; if (keyPart) { if (filter.length > 0) { filter.push("and") } filter.push([dataSourceKey[i], operation, keyPart]) } } } else { filter = [dataSourceKey, operation, key] } return filter }; _proto5._getLastItemIndex = function() { return this.items(true).length - 1 }; return FocusDataControllerExtender }(Base); const editing = Base => function(_Base5) { _inheritsLoose(FocusEditingControllerExtender, _Base5); function FocusEditingControllerExtender() { return _Base5.apply(this, arguments) || this } var _proto6 = FocusEditingControllerExtender.prototype; _proto6._deleteRowCore = function(rowIndex) { const deferred = _Base5.prototype._deleteRowCore.apply(this, arguments); const rowKey = this._dataController.getKeyByRowIndex(rowIndex); deferred.done(() => { const rowIndex = this._dataController.getRowIndexByKey(rowKey); const visibleRows = this._dataController.getVisibleRows(); if (-1 === rowIndex && !visibleRows.length) { this._focusController._resetFocusedRow() } }) }; return FocusEditingControllerExtender }(Base); const rowsView = Base => function(_Base6) { _inheritsLoose(RowsViewFocusController, _Base6); function RowsViewFocusController() { return _Base6.apply(this, arguments) || this } var _proto7 = RowsViewFocusController.prototype; _proto7._createRow = function(row) { const $row = _Base6.prototype._createRow.apply(this, arguments); if (this.option("focusedRowEnabled") && row) { if (this._focusController.isRowFocused(row.key)) { $row.addClass("dx-row-focused") } } return $row }; _proto7._checkRowKeys = function(options) { _Base6.prototype._checkRowKeys.apply(this, arguments); if (this.option("focusedRowEnabled") && this.option("dataSource")) { const store = this._dataController.store(); if (store && !store.key()) { this._dataController.fireError("E1042", "Row focusing") } } }; _proto7._update = function(change) { if ("updateFocusedRow" === change.changeType) { if (this.option("focusedRowEnabled")) { this._focusController.updateFocusedRow(change) } } else { _Base6.prototype._update.call(this, change) } }; _proto7.updateFocusElementTabIndex = function($cellElements, preventScroll) { if (this.option("focusedRowEnabled")) { this._setFocusedRowElementTabIndex(preventScroll) } else { _Base6.prototype.updateFocusElementTabIndex.call(this, $cellElements) } }; _proto7._setFocusedRowElementTabIndex = function(preventScroll) { var _a; const focusedRowKey = this.option("focusedRowKey"); const tabIndex = null !== (_a = this.option("tabIndex")) && void 0 !== _a ? _a : 0; const columnsController = this._columnsController; let rowIndex = this._dataController.getRowIndexByKey(focusedRowKey); let columnIndex = this.option("focusedColumnIndex"); const $row = this._findRowElementForTabIndex(); const dataSource = this._dataController.dataSource(); const operationTypes = null === dataSource || void 0 === dataSource ? void 0 : dataSource.operationTypes(); const isPaging = !operationTypes || operationTypes.paging; if (!(0, _type.isDefined)(this._scrollToFocusOnResize)) { this._scrollToFocusOnResize = () => { this.scrollToElementVertically(this._findRowElementForTabIndex()); this.resizeCompleted.remove(this._scrollToFocusOnResize) } } $row.attr("tabIndex", tabIndex); const rowIndexFromOption = this.option("focusedRowIndex") - this._dataController.getRowIndexOffset(true); if (!isPaging && rowIndex < 0 && rowIndexFromOption >= 0) { this._focusController.updateFocusedRow({ focusedRowIndex: rowIndexFromOption, preventScroll: preventScroll }) } if (rowIndex >= 0 && !preventScroll) { if (columnIndex < 0) { columnIndex = 0 } rowIndex += this._dataController.getRowIndexOffset(); columnIndex += columnsController.getColumnIndexOffset(); this._keyboardNavigationController.setFocusedCellPosition(rowIndex, columnIndex); if (this._focusController.isAutoNavigateToFocusedRow()) { if (!isPaging && !this._dataController.isPagingByRendering()) { this.resizeCompleted.remove(this._scrollToFocusOnResize); this.resizeCompleted.add(this._scrollToFocusOnResize) } } } }; _proto7._findRowElementForTabIndex = function() { const focusedRowKey = this.option("focusedRowKey"); const rowIndex = this._dataController.getRowIndexByKey(focusedRowKey); return (0, _renderer.default)(this.getRowElement(rowIndex >= 0 ? rowIndex : 0)) }; _proto7.scrollToRowElement = function(key) { const rowIndex = this._dataController.getRowIndexByKey(key); const $row = (0, _renderer.default)(this.getRow(rowIndex)); return this.scrollToElementVertically($row) }; _proto7.scrollToElementVertically = function($row) { const scrollable = this.getScrollable(); if (scrollable && $row.length) { const position = scrollable.getScrollElementPosition($row, "vertical"); return this.scrollTopPosition(position) } return (new _deferred.Deferred).resolve() }; _proto7.scrollTopPosition = function(scrollTop) { const d = new _deferred.Deferred; const scrollable = this.getScrollable(); if (scrollable) { const currentScrollTop = scrollable.scrollTop(); const scrollHandler = () => { scrollable.off("scroll", scrollHandler); d.resolve() }; if (scrollTop !== currentScrollTop) { scrollable.on("scroll", scrollHandler); this._dataController.resetFilterApplying(); scrollable.scrollTo({ top: scrollTop }); return d.promise() } } return d.resolve() }; return RowsViewFocusController }(Base); const focusModule = { defaultOptions: () => ({ focusedRowEnabled: false, autoNavigateToFocusedRow: true, focusedRowKey: null, focusedRowIndex: -1, focusedColumnIndex: -1 }), controllers: { focus: FocusController }, extenders: { controllers: { keyboardNavigation: keyboardNavigation, editorFactory: editorFactory, columns: columns, data: data, editing: editing }, views: { rowsView: rowsView } } }; exports.focusModule = focusModule;