UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

1,062 lines (1,052 loc) • 97.7 kB
/** * DevExtreme (cjs/__internal/grids/grid_core/keyboard_navigation/module.js) * Version: 22.1.9 * Build date: Tue Apr 18 2023 * * Copyright (c) 2012 - 2023 Developer Express Inc. ALL RIGHTS RESERVED * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/ */ "use strict"; var __createBinding = this && this.__createBinding || (Object.create ? function(o, m, k, k2) { if (void 0 === k2) { k2 = k } Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k] } }) } : function(o, m, k, k2) { if (void 0 === k2) { k2 = k } o[k2] = m[k] }); var __setModuleDefault = this && this.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }) } : function(o, v) { o.default = v }); var __importStar = this && this.__importStar || function(mod) { if (mod && mod.__esModule) { return mod } var result = {}; if (null != mod) { for (var k in mod) { if ("default" !== k && Object.prototype.hasOwnProperty.call(mod, k)) { __createBinding(result, mod, k) } } } __setModuleDefault(result, mod); return result }; var __importDefault = this && this.__importDefault || function(mod) { return mod && mod.__esModule ? mod : { default: mod } }; Object.defineProperty(exports, "__esModule", { value: true }); exports.keyboardNavigationModule = void 0; var size_1 = require("../../../../core/utils/size"); var renderer_1 = __importDefault(require("../../../../core/renderer")); var dom_adapter_1 = __importDefault(require("../../../../core/dom_adapter")); var events_engine_1 = __importDefault(require("../../../../events/core/events_engine")); var type_1 = require("../../../../core/utils/type"); var index_1 = require("../../../../events/utils/index"); var pointer_1 = __importDefault(require("../../../../events/pointer")); var click_1 = require("../../../../events/click"); var common_1 = require("../../../../core/utils/common"); var browser_1 = __importDefault(require("../../../../core/utils/browser")); var short_1 = require("../../../../events/short"); var devices_1 = __importDefault(require("../../../../core/devices")); var accessibility = __importStar(require("../../../../ui/shared/accessibility")); var selectors_1 = require("../../../../ui/widget/selectors"); var module_utils_1 = __importDefault(require("../module_utils")); var modules_1 = __importDefault(require("../modules")); var dom_1 = require("./dom"); var ROWS_VIEW_CLASS = "rowsview"; var EDIT_FORM_CLASS = "edit-form"; var GROUP_FOOTER_CLASS = "group-footer"; var ROW_CLASS = "dx-row"; var DATA_ROW_CLASS = "dx-data-row"; var GROUP_ROW_CLASS = "dx-group-row"; var HEADER_ROW_CLASS = "dx-header-row"; var EDIT_FORM_ITEM_CLASS = "edit-form-item"; var MASTER_DETAIL_ROW_CLASS = "dx-master-detail-row"; var FREESPACE_ROW_CLASS = "dx-freespace-row"; var VIRTUAL_ROW_CLASS = "dx-virtual-row"; var MASTER_DETAIL_CELL_CLASS = "dx-master-detail-cell"; var EDITOR_CELL_CLASS = "dx-editor-cell"; var DROPDOWN_EDITOR_OVERLAY_CLASS = "dx-dropdowneditor-overlay"; var COMMAND_EXPAND_CLASS = "dx-command-expand"; var COMMAND_SELECT_CLASS = "dx-command-select"; var COMMAND_EDIT_CLASS = "dx-command-edit"; var COMMAND_CELL_SELECTOR = "[class^=dx-command]"; var CELL_FOCUS_DISABLED_CLASS = "dx-cell-focus-disabled"; var DATEBOX_WIDGET_NAME = "dxDateBox"; var FOCUS_STATE_CLASS = "dx-state-focused"; var WIDGET_CLASS = "dx-widget"; var REVERT_BUTTON_CLASS = "dx-revert-button"; var FAST_EDITING_DELETE_KEY = "delete"; var INTERACTIVE_ELEMENTS_SELECTOR = "input:not([type='hidden']), textarea, a, select, button, [tabindex], .dx-checkbox"; var NON_FOCUSABLE_ELEMENTS_SELECTOR = INTERACTIVE_ELEMENTS_SELECTOR + ", .dx-dropdowneditor-icon"; var EDIT_MODE_ROW = "row"; var EDIT_MODE_FORM = "form"; var EDIT_MODE_BATCH = "batch"; var EDIT_MODE_CELL = "cell"; var FOCUS_TYPE_ROW = "row"; var FOCUS_TYPE_CELL = "cell"; var COLUMN_HEADERS_VIEW = "columnHeadersView"; var FUNCTIONAL_KEYS = ["shift", "control", "alt"]; function isGroupRow($row) { return $row && $row.hasClass(GROUP_ROW_CLASS) } function isDetailRow($row) { return $row && $row.hasClass(MASTER_DETAIL_ROW_CLASS) } function isDataRow($row) { return $row && !isGroupRow($row) && !isDetailRow($row) } function isNotFocusedRow($row) { return !$row || $row.hasClass(FREESPACE_ROW_CLASS) || $row.hasClass(VIRTUAL_ROW_CLASS) } function isEditorCell(that, $cell) { return !that._isRowEditMode() && $cell && !$cell.hasClass(COMMAND_SELECT_CLASS) && $cell.hasClass(EDITOR_CELL_CLASS) } function isElementDefined($element) { return type_1.isDefined($element) && $element.length > 0 } function isMobile() { return "desktop" !== devices_1.default.current().deviceType } function isCellInHeaderRow($cell) { return !!$cell.parent("." + HEADER_ROW_CLASS).length } function isFixedColumnIndexOffsetRequired(that, column) { var rtlEnabled = that.option("rtlEnabled"); var result = false; if (rtlEnabled) { result = !("right" === column.fixedPosition || type_1.isDefined(column.command) && !type_1.isDefined(column.fixedPosition)) } else { result = !(!type_1.isDefined(column.fixedPosition) || "left" === column.fixedPosition) } return result } function shouldPreventScroll(that) { var keyboardController = that.getController("keyboardNavigation"); return keyboardController._isVirtualScrolling() ? that.option("focusedRowIndex") === keyboardController.getRowIndex() : false } var KeyboardNavigationController = modules_1.default.ViewController.inherit({ init: function() { var _this = this; this._dataController = this.getController("data"); this._selectionController = this.getController("selection"); this._editingController = this.getController("editing"); this._headerPanel = this.getView("headerPanel"); this._columnsController = this.getController("columns"); this._editorFactory = this.getController("editorFactory"); if (this.isKeyboardEnabled()) { accessibility.subscribeVisibilityChange(); this._updateFocusTimeout = null; this._fastEditingStarted = false; this._focusedCellPosition = {}; this._canceledCellPosition = null; this._editorFactory.focused.add((function($element) { _this.setupFocusedView(); if (_this._isNeedScroll) { if ($element.is(":visible") && _this._focusedView && _this._focusedView.getScrollable) { _this._focusedView._scrollToElement($element); _this._isNeedScroll = false } } })); this._initViewHandlers(); this._initDocumentHandlers(); this.createAction("onKeyDown") } }, _initViewHandlers: function() { var _this = this; var rowsView = this.getView("rowsView"); var rowsViewFocusHandler = function(event) { var $element = renderer_1.default(event.target); var isRelatedTargetInRowsView = renderer_1.default(event.relatedTarget).closest(rowsView.element()).length; var isLink = $element.is("a"); if (event.relatedTarget && isLink && !isRelatedTargetInRowsView && _this._isEventInCurrentGrid(event)) { var $focusedCell = _this._getFocusedCell(); $focusedCell = !isElementDefined($focusedCell) ? rowsView.getCellElements(0).filter("[tabindex]").eq(0) : $focusedCell; if (!$element.closest($focusedCell).length) { event.preventDefault(); events_engine_1.default.trigger($focusedCell, "focus") } } }; rowsView.renderCompleted.add((function(e) { var $rowsView = rowsView.element(); var isFullUpdate = !e || "refresh" === e.changeType; var isFocusedViewCorrect = _this._focusedView && _this._focusedView.name === rowsView.name; var needUpdateFocus = false; var isAppend = e && ("append" === e.changeType || "prepend" === e.changeType); var $focusedElement = renderer_1.default(":focus"); var isFocusedElementCorrect = !$focusedElement.length || $focusedElement.closest($rowsView).length; events_engine_1.default.off($rowsView, "focusin", rowsViewFocusHandler); events_engine_1.default.on($rowsView, "focusin", rowsViewFocusHandler); _this._initPointerEventHandler(); _this._initKeyDownHandler(); _this._setRowsViewAttributes(); if (isFocusedViewCorrect && isFocusedElementCorrect) { needUpdateFocus = _this._isNeedFocus ? !isAppend : _this._isHiddenFocus && isFullUpdate && !(null === e || void 0 === e ? void 0 : e.virtualColumnsScrolling); needUpdateFocus && _this._updateFocus(true) } })) }, _initDocumentHandlers: function() { var _this = this; var document = dom_adapter_1.default.getDocument(); this._documentClickHandler = this.createAction((function(e) { var $target = renderer_1.default(e.event.target); var isCurrentRowsViewClick = _this._isEventInCurrentGrid(e.event) && $target.closest("." + _this.addWidgetPrefix(ROWS_VIEW_CLASS)).length; var isEditorOverlay = $target.closest("." + DROPDOWN_EDITOR_OVERLAY_CLASS).length; var columnsResizerController = _this.getController("columnsResizer"); var isColumnResizing = !!columnsResizerController && columnsResizerController.isResizing(); if (!isCurrentRowsViewClick && !isEditorOverlay && !isColumnResizing) { var targetInsideFocusedView = _this._focusedView ? $target.parents().filter(_this._focusedView.element()).length > 0 : false; !targetInsideFocusedView && _this._resetFocusedCell(true); _this._resetFocusedView() } })); events_engine_1.default.on(document, index_1.addNamespace(pointer_1.default.down, "dxDataGridKeyboardNavigation"), this._documentClickHandler) }, _setRowsViewAttributes: function() { var $rowsView = this._getRowsViewElement(); var isGridEmpty = !this._dataController.getVisibleRows().length; if (isGridEmpty) { this._applyTabIndexToElement($rowsView) } }, _initPointerEventHandler: function() { var pointerEventName = !isMobile() ? pointer_1.default.down : click_1.name; var clickSelector = "." + ROW_CLASS + " > td, ." + ROW_CLASS; var $rowsView = this._getRowsViewElement(); if (!type_1.isDefined(this._pointerEventAction)) { this._pointerEventAction = this.createAction(this._pointerEventHandler) } events_engine_1.default.off($rowsView, index_1.addNamespace(pointerEventName, "dxDataGridKeyboardNavigation"), this._pointerEventAction); events_engine_1.default.on($rowsView, index_1.addNamespace(pointerEventName, "dxDataGridKeyboardNavigation"), clickSelector, this._pointerEventAction) }, _initKeyDownHandler: function() { var _this = this; var $rowsView = this._getRowsViewElement(); short_1.keyboard.off(this._keyDownListener); this._keyDownListener = short_1.keyboard.on($rowsView, null, (function(e) { return _this._keyDownHandler(e) })) }, dispose: function() { this.callBase(); this._resetFocusedView(); short_1.keyboard.off(this._keyDownListener); events_engine_1.default.off(dom_adapter_1.default.getDocument(), index_1.addNamespace(pointer_1.default.down, "dxDataGridKeyboardNavigation"), this._documentClickHandler); clearTimeout(this._updateFocusTimeout); accessibility.unsubscribeVisibilityChange() }, optionChanged: function(args) { switch (args.name) { case "keyboardNavigation": case "useLegacyKeyboardNavigation": args.handled = true; break; default: this.callBase(args) } }, isRowFocusType: function() { return this.focusType === FOCUS_TYPE_ROW }, isCellFocusType: function() { return this.focusType === FOCUS_TYPE_CELL }, setRowFocusType: function() { if (this.option("focusedRowEnabled")) { this.focusType = FOCUS_TYPE_ROW } }, setCellFocusType: function() { this.focusType = FOCUS_TYPE_CELL }, _keyDownHandler: function(e) { var _a; var needStopPropagation = true; this._isNeedFocus = true; this._isNeedScroll = true; var isHandled = this._processOnKeyDown(e); var isEditing = null === (_a = this._editingController) || void 0 === _a ? void 0 : _a.isEditing(); var originalEvent = e.originalEvent; if (originalEvent.isDefaultPrevented()) { this._isNeedFocus = false; this._isNeedScroll = false; return }!FUNCTIONAL_KEYS.includes(e.keyName) && this._updateFocusedCellPositionByTarget(originalEvent.target); if (!isHandled) { switch (e.keyName) { case "leftArrow": case "rightArrow": this._leftRightKeysHandler(e, isEditing); isHandled = true; break; case "upArrow": case "downArrow": if (e.ctrl) { accessibility.selectView("rowsView", this, originalEvent) } else { this._upDownKeysHandler(e, isEditing) } isHandled = true; break; case "pageUp": case "pageDown": this._pageUpDownKeyHandler(e); isHandled = true; break; case "space": isHandled = this._spaceKeyHandler(e, isEditing); break; case "A": if (index_1.isCommandKeyPressed(e.originalEvent)) { this._ctrlAKeyHandler(e, isEditing); isHandled = true } else { isHandled = this._beginFastEditing(e.originalEvent) } break; case "tab": this._tabKeyHandler(e, isEditing); isHandled = true; break; case "enter": this._enterKeyHandler(e, isEditing); isHandled = true; break; case "escape": this._escapeKeyHandler(e, isEditing); isHandled = true; break; case "F": if (index_1.isCommandKeyPressed(e.originalEvent)) { this._ctrlFKeyHandler(e); isHandled = true } else { isHandled = this._beginFastEditing(e.originalEvent) } break; case "F2": this._f2KeyHandler(); isHandled = true; break; case "del": case "backspace": if (this._isFastEditingAllowed() && !this._isFastEditingStarted()) { isHandled = this._beginFastEditing(originalEvent, true) } } if (!isHandled && !this._beginFastEditing(originalEvent)) { this._isNeedFocus = false; this._isNeedScroll = false; needStopPropagation = false } if (needStopPropagation) { originalEvent.stopPropagation() } } }, _processOnKeyDown: function(eventArgs) { var originalEvent = eventArgs.originalEvent; var args = { handled: false, event: originalEvent }; this.executeAction("onKeyDown", args); eventArgs.ctrl = originalEvent.ctrlKey; eventArgs.alt = originalEvent.altKey; eventArgs.shift = originalEvent.shiftKey; return !!args.handled }, _closeEditCell: function() { var _this = this; setTimeout((function() { _this._editingController.closeEditCell() })) }, _leftRightKeysHandler: function(eventArgs, isEditing) { var rowIndex = this.getVisibleRowIndex(); var $event = eventArgs.originalEvent; var $row = this._focusedView && this._focusedView.getRow(rowIndex); var directionCode = this._getDirectionCodeByKey(eventArgs.keyName); var isEditingNavigationMode = this._isFastEditingStarted(); var allowNavigate = (!isEditing || isEditingNavigationMode) && isDataRow($row); if (allowNavigate) { this.setCellFocusType(); isEditingNavigationMode && this._closeEditCell(); if (this._isVirtualColumnRender()) { this._processVirtualHorizontalPosition(directionCode) } var $cell = this._getNextCell(directionCode); if (isElementDefined($cell)) { this._arrowKeysHandlerFocusCell($event, $cell, directionCode) } $event && $event.preventDefault() } }, _upDownKeysHandler: function(eventArgs, isEditing) { var _a, _b; var visibleRowIndex = this.getVisibleRowIndex(); var $row = this._focusedView && this._focusedView.getRow(visibleRowIndex); var $event = eventArgs.originalEvent; var isUpArrow = "upArrow" === eventArgs.keyName; var dataSource = this._dataController.dataSource(); var isRowEditingInCurrentRow = null === (_b = null === (_a = this._editingController) || void 0 === _a ? void 0 : _a.isEditRowByIndex) || void 0 === _b ? void 0 : _b.call(_a, visibleRowIndex); var isEditingNavigationMode = this._isFastEditingStarted(); var allowNavigate = (!isRowEditingInCurrentRow || !isEditing || isEditingNavigationMode) && $row && !isDetailRow($row); if (allowNavigate) { isEditingNavigationMode && this._closeEditCell(); if (!this._navigateNextCell($event, eventArgs.keyName)) { if (this._isVirtualRowRender() && isUpArrow && dataSource && !dataSource.isLoading()) { var rowHeight = size_1.getOuterHeight($row); var rowIndex = this._focusedCellPosition.rowIndex - 1; this._scrollBy(0, -rowHeight, rowIndex, $event) } } $event && $event.preventDefault() } }, _pageUpDownKeyHandler: function(eventArgs) { var pageIndex = this._dataController.pageIndex(); var pageCount = this._dataController.pageCount(); var pagingEnabled = this.option("paging.enabled"); var isPageUp = "pageUp" === eventArgs.keyName; var pageStep = isPageUp ? -1 : 1; var scrollable = this.getView("rowsView").getScrollable(); if (pagingEnabled && !this._isVirtualScrolling()) { if ((isPageUp ? pageIndex > 0 : pageIndex < pageCount - 1) && !this._isVirtualScrolling()) { this._dataController.pageIndex(pageIndex + pageStep); eventArgs.originalEvent.preventDefault() } } else if (scrollable && size_1.getHeight(scrollable.container()) < size_1.getHeight(scrollable.$content())) { this._scrollBy(0, size_1.getHeight(scrollable.container()) * pageStep); eventArgs.originalEvent.preventDefault() } }, _spaceKeyHandler: function(eventArgs, isEditing) { var rowIndex = this.getVisibleRowIndex(); var $target = renderer_1.default(eventArgs.originalEvent && eventArgs.originalEvent.target); if (this.option("selection") && "none" !== this.option("selection").mode && !isEditing) { var isFocusedRowElement = "row" === this._getElementType($target) && this.isRowFocusType() && isDataRow($target); var isFocusedSelectionCell = $target.hasClass(COMMAND_SELECT_CLASS); if (isFocusedSelectionCell && "onClick" === this.option("selection.showCheckBoxesMode")) { this._selectionController.startSelectionWithCheckboxes() } if (isFocusedRowElement || $target.parent().hasClass(DATA_ROW_CLASS) || $target.hasClass(this.addWidgetPrefix(ROWS_VIEW_CLASS))) { this._selectionController.changeItemSelection(rowIndex, { shift: eventArgs.shift, control: eventArgs.ctrl }); eventArgs.originalEvent.preventDefault(); return true } return false } return this._beginFastEditing(eventArgs.originalEvent) }, _ctrlAKeyHandler: function(eventArgs, isEditing) { if (!isEditing && !eventArgs.alt && "multiple" === this.option("selection.mode") && this.option("selection.allowSelectAll")) { this._selectionController.selectAll(); eventArgs.originalEvent.preventDefault() } }, _tabKeyHandler: function(eventArgs, isEditing) { var editingOptions = this.option("editing"); var direction = eventArgs.shift ? "previous" : "next"; var isCellPositionDefined = type_1.isDefined(this._focusedCellPosition) && !type_1.isEmptyObject(this._focusedCellPosition); var isOriginalHandlerRequired = !isCellPositionDefined || !eventArgs.shift && this._isLastValidCell(this._focusedCellPosition) || eventArgs.shift && this._isFirstValidCell(this._focusedCellPosition); var eventTarget = eventArgs.originalEvent.target; var focusedViewElement = this._focusedView && this._focusedView.element(); if (this._handleTabKeyOnMasterDetailCell(eventTarget, direction)) { return } renderer_1.default(focusedViewElement).addClass(FOCUS_STATE_CLASS); if (editingOptions && eventTarget && !isOriginalHandlerRequired) { if (renderer_1.default(eventTarget).hasClass(this.addWidgetPrefix(ROWS_VIEW_CLASS))) { this._resetFocusedCell() } if (this._isVirtualColumnRender()) { this._processVirtualHorizontalPosition(direction) } if (isEditing) { if (!this._editingCellTabHandler(eventArgs, direction)) { return } } else if (this._targetCellTabHandler(eventArgs, direction)) { isOriginalHandlerRequired = true } } if (isOriginalHandlerRequired) { this._editorFactory.loseFocus(); if (this._editingController.isEditing() && !this._isRowEditMode()) { this._resetFocusedCell(true); this._resetFocusedView(); this._closeEditCell() } } else { eventArgs.originalEvent.preventDefault() } }, _getMaxHorizontalOffset: function() { var scrollable = this.component.getScrollable(); var rowsView = this.getView("rowsView"); var offset = scrollable ? scrollable.scrollWidth() - size_1.getWidth(rowsView.element()) : 0; return offset }, _isColumnRendered: function(columnIndex) { var allVisibleColumns = this._columnsController.getVisibleColumns(null, true); var renderedVisibleColumns = this._columnsController.getVisibleColumns(); var column = allVisibleColumns[columnIndex]; var result = false; if (column) { result = renderedVisibleColumns.indexOf(column) >= 0 } return result }, _isFixedColumn: function(columnIndex) { var allVisibleColumns = this._columnsController.getVisibleColumns(null, true); var column = allVisibleColumns[columnIndex]; return !!column && !!column.fixed }, _isColumnVirtual: function(columnIndex) { var localColumnIndex = columnIndex - this._columnsController.getColumnIndexOffset(); var visibleColumns = this._columnsController.getVisibleColumns(); var column = visibleColumns[localColumnIndex]; return !!column && "virtual" === column.command }, _processVirtualHorizontalPosition: function(direction) { var scrollable = this.component.getScrollable(); var columnIndex = this.getColumnIndex(); var nextColumnIndex; var horizontalScrollPosition = 0; var needToScroll = false; switch (direction) { case "next": case "nextInRow": var columnsCount = this._getVisibleColumnCount(); nextColumnIndex = columnIndex + 1; horizontalScrollPosition = this.option("rtlEnabled") ? this._getMaxHorizontalOffset() : 0; if ("next" === direction) { needToScroll = columnsCount === nextColumnIndex || this._isFixedColumn(columnIndex) && !this._isColumnRendered(nextColumnIndex) } else { needToScroll = columnsCount > nextColumnIndex && this._isFixedColumn(columnIndex) && !this._isColumnRendered(nextColumnIndex) } break; case "previous": case "previousInRow": nextColumnIndex = columnIndex - 1; horizontalScrollPosition = this.option("rtlEnabled") ? 0 : this._getMaxHorizontalOffset(); if ("previous" === direction) { var columnIndexOffset = this._columnsController.getColumnIndexOffset(); var leftEdgePosition = nextColumnIndex < 0 && 0 === columnIndexOffset; needToScroll = leftEdgePosition || this._isFixedColumn(columnIndex) && !this._isColumnRendered(nextColumnIndex) } else { needToScroll = nextColumnIndex >= 0 && this._isFixedColumn(columnIndex) && !this._isColumnRendered(nextColumnIndex) } } if (needToScroll) { scrollable.scrollTo({ left: horizontalScrollPosition }) } else if (type_1.isDefined(nextColumnIndex) && type_1.isDefined(direction) && this._isColumnVirtual(nextColumnIndex)) { horizontalScrollPosition = this._getHorizontalScrollPositionOffset(direction); 0 !== horizontalScrollPosition && scrollable.scrollBy({ left: horizontalScrollPosition, top: 0 }) } }, _getHorizontalScrollPositionOffset: function(direction) { var positionOffset = 0; var $currentCell = this._getCell(this._focusedCellPosition); var currentCellWidth = $currentCell && size_1.getOuterWidth($currentCell); if (currentCellWidth > 0) { var rtlMultiplier = this.option("rtlEnabled") ? -1 : 1; positionOffset = "nextInRow" === direction || "next" === direction ? currentCellWidth * rtlMultiplier : currentCellWidth * rtlMultiplier * -1 } return positionOffset }, _editingCellTabHandler: function(eventArgs, direction) { var eventTarget = eventArgs.originalEvent.target; var $cell = this._getCellElementFromTarget(eventTarget); var isEditingAllowed; var $event = eventArgs.originalEvent; var elementType = this._getElementType(eventTarget); if ($cell.is(COMMAND_CELL_SELECTOR)) { return !this._targetCellTabHandler(eventArgs, direction) } this._updateFocusedCellPosition($cell); var nextCellInfo = this._getNextCellByTabKey($event, direction, elementType); $cell = nextCellInfo.$cell; if (!$cell || this._handleTabKeyOnMasterDetailCell($cell, direction)) { return false } var columnsController = this._columnsController; var cellIndex = this.getView("rowsView").getCellIndex($cell); var columnIndex = cellIndex + columnsController.getColumnIndexOffset(); var column = columnsController.getVisibleColumns(null, true)[columnIndex]; var $row = $cell.parent(); var rowIndex = this._getRowIndex($row); var row = this._dataController.items()[rowIndex]; var editingController = this._editingController; if (column && column.allowEditing) { var isDataRow_1 = !row || "data" === row.rowType; isEditingAllowed = editingController.allowUpdating({ row: row }) ? isDataRow_1 : row && row.isNewRow } if (!isEditingAllowed) { this._closeEditCell() } if (this._focusCell($cell, !nextCellInfo.isHighlighted)) { if (!this._isRowEditMode() && isEditingAllowed) { this._editFocusedCell() } else { this._focusInteractiveElement($cell, eventArgs.shift) } } return true }, _targetCellTabHandler: function(eventArgs, direction) { var $event = eventArgs.originalEvent; var eventTarget = $event.target; var $cell = this._getCellElementFromTarget(eventTarget); var $lastInteractiveElement = this._getInteractiveElement($cell, !eventArgs.shift); var isOriginalHandlerRequired = false; var elementType; if (!isEditorCell(this, $cell) && $lastInteractiveElement.length && eventTarget !== $lastInteractiveElement.get(0)) { isOriginalHandlerRequired = true } else { if (void 0 === this._focusedCellPosition.rowIndex && renderer_1.default(eventTarget).hasClass(ROW_CLASS)) { this._updateFocusedCellPosition($cell) } elementType = this._getElementType(eventTarget); if (this.isRowFocusType()) { this.setCellFocusType(); if ("row" === elementType && isDataRow(renderer_1.default(eventTarget))) { eventTarget = this.getFirstValidCellInRow(renderer_1.default(eventTarget)); elementType = this._getElementType(eventTarget) } } var nextCellInfo = this._getNextCellByTabKey($event, direction, elementType); $cell = nextCellInfo.$cell; if (!$cell) { return false } $cell = this._checkNewLineTransition($event, $cell); if (!$cell) { return false } this._focusCell($cell, !nextCellInfo.isHighlighted); if (!isEditorCell(this, $cell)) { this._focusInteractiveElement($cell, eventArgs.shift) } } return isOriginalHandlerRequired }, _getNextCellByTabKey: function($event, direction, elementType) { var $cell = this._getNextCell(direction, elementType); var args = $cell && this._fireFocusedCellChanging($event, $cell, true); if (!args || args.cancel) { return {} } if (args.$newCellElement) { $cell = args.$newCellElement } return { $cell: $cell, isHighlighted: args.isHighlighted } }, _checkNewLineTransition: function($event, $cell) { var rowIndex = this.getVisibleRowIndex(); var $row = $cell.parent(); if (rowIndex !== this._getRowIndex($row)) { var cellPosition = this._getCellPosition($cell); var args = this._fireFocusedRowChanging($event, $row); if (args.cancel) { return } if (args.rowIndexChanged) { this.setFocusedColumnIndex(cellPosition.columnIndex); $cell = this._getFocusedCell() } } return $cell }, _enterKeyHandler: function(eventArgs, isEditing) { var $cell = this._getFocusedCell(); var rowIndex = this.getVisibleRowIndex(); var $row = this._focusedView && this._focusedView.getRow(rowIndex); if (this.option("grouping.allowCollapsing") && isGroupRow($row) || this.option("masterDetail.enabled") && $cell && $cell.hasClass(COMMAND_EXPAND_CLASS)) { var key = this._dataController.getKeyByRowIndex(rowIndex); var item = this._dataController.items()[rowIndex]; if (void 0 !== key && item && item.data && !item.data.isContinuation) { this._dataController.changeRowExpand(key) } } else { this._processEnterKeyForDataCell(eventArgs, isEditing) } }, _processEnterKeyForDataCell: function(eventArgs, isEditing) { var direction = this._getEnterKeyDirection(eventArgs); var allowEditingOnEnterKey = this._allowEditingOnEnterKey(); if (isEditing || !allowEditingOnEnterKey && direction) { this._handleEnterKeyEditingCell(eventArgs.originalEvent); if ("next" === direction || "previous" === direction) { this._targetCellTabHandler(eventArgs, direction) } else if ("upArrow" === direction || "downArrow" === direction) { this._navigateNextCell(eventArgs.originalEvent, direction) } } else if (allowEditingOnEnterKey) { this._startEditing(eventArgs) } }, _getEnterKeyDirection: function(eventArgs) { var enterKeyDirection = this.option("keyboardNavigation.enterKeyDirection"); var isShift = eventArgs.shift; if ("column" === enterKeyDirection) { return isShift ? "upArrow" : "downArrow" } if ("row" === enterKeyDirection) { return isShift ? "previous" : "next" } }, _handleEnterKeyEditingCell: function(event) { var target = event.target; var $cell = this._getCellElementFromTarget(target); var isRowEditMode = this._isRowEditMode(); this._updateFocusedCellPosition($cell); if (isRowEditMode) { this._focusEditFormCell($cell); setTimeout(this._editingController.saveEditData.bind(this._editingController)) } else { events_engine_1.default.trigger(renderer_1.default(target), "change"); this._closeEditCell(); event.preventDefault() } }, _escapeKeyHandler: function(eventArgs, isEditing) { var $cell = this._getCellElementFromTarget(eventArgs.originalEvent.target); if (isEditing) { this._updateFocusedCellPosition($cell); if (!this._isRowEditMode()) { if ("cell" === this._editingController.getEditMode()) { this._editingController.cancelEditData() } else { this._closeEditCell() } } else { this._focusEditFormCell($cell); this._editingController.cancelEditData(); if (0 === this._dataController.items().length) { this._resetFocusedCell(); this._editorFactory.loseFocus() } } eventArgs.originalEvent.preventDefault() } }, _ctrlFKeyHandler: function(eventArgs) { if (this.option("searchPanel.visible")) { var searchTextEditor = this._headerPanel.getSearchTextEditor(); if (searchTextEditor) { searchTextEditor.focus(); eventArgs.originalEvent.preventDefault() } } }, _f2KeyHandler: function() { var isEditing = this._editingController.isEditing(); var rowIndex = this.getVisibleRowIndex(); var $row = this._focusedView && this._focusedView.getRow(rowIndex); if (!isEditing && isDataRow($row)) { this._startEditing() } }, _navigateNextCell: function($event, keyCode) { var $cell = this._getNextCell(keyCode); var directionCode = this._getDirectionCodeByKey(keyCode); var isCellValid = $cell && this._isCellValid($cell); var result = isCellValid ? this._arrowKeysHandlerFocusCell($event, $cell, directionCode) : false; return result }, _arrowKeysHandlerFocusCell: function($event, $nextCell, direction) { var isVerticalDirection = "prevRow" === direction || "nextRow" === direction; var args = this._fireFocusChangingEvents($event, $nextCell, isVerticalDirection, true); $nextCell = args.$newCellElement; if (!args.cancel && this._isCellValid($nextCell)) { this._focus($nextCell, !args.isHighlighted); return true } return false }, _beginFastEditing: function(originalEvent, isDeleting) { if (!this._isFastEditingAllowed() || originalEvent.altKey || originalEvent.ctrlKey || this._editingController.isEditing()) { return false } if (isDeleting) { this._startEditing(originalEvent, FAST_EDITING_DELETE_KEY) } else { var key = originalEvent.key; var keyCode = originalEvent.keyCode || originalEvent.which; var fastEditingKey = key || keyCode && String.fromCharCode(keyCode); if (fastEditingKey && (1 === fastEditingKey.length || fastEditingKey === FAST_EDITING_DELETE_KEY)) { this._startEditing(originalEvent, fastEditingKey) } } return true }, _pointerEventHandler: function(e) { var event = e.event || e; var $target = renderer_1.default(event.currentTarget); var rowsView = this.getView("rowsView"); var focusedViewElement = rowsView && rowsView.element(); var $parent = $target.parent(); var isInteractiveElement = renderer_1.default(event.target).is(INTERACTIVE_ELEMENTS_SELECTOR); var isRevertButton = !!renderer_1.default(event.target).closest("." + REVERT_BUTTON_CLASS).length; var isExpandCommandCell = $target.hasClass(COMMAND_EXPAND_CLASS); if (!this._isEventInCurrentGrid(event)) { return } if (!isRevertButton && (this._isCellValid($target, !isInteractiveElement) || isExpandCommandCell)) { $target = this._isInsideEditForm($target) ? renderer_1.default(event.target) : $target; this._focusView(); renderer_1.default(focusedViewElement).removeClass(FOCUS_STATE_CLASS); if ($parent.hasClass(FREESPACE_ROW_CLASS)) { this._updateFocusedCellPosition($target); this._applyTabIndexToElement(this._focusedView.element()); this._focusedView.focus(true) } else if (!this._isMasterDetailCell($target)) { this._clickTargetCellHandler(event, $target) } else { this._updateFocusedCellPosition($target) } } else if ($target.is("td")) { this._resetFocusedCell() } }, _clickTargetCellHandler: function(event, $cell) { var columnIndex = this.getView("rowsView").getCellIndex($cell); var column = this._columnsController.getVisibleColumns()[columnIndex]; var isCellEditMode = this._isCellEditMode(); this.setCellFocusType(); var args = this._fireFocusChangingEvents(event, $cell, true); $cell = args.$newCellElement; if (!args.cancel) { if (args.resetFocusedRow) { this.getController("focus")._resetFocusedRow(); return } if (args.rowIndexChanged) { $cell = this._getFocusedCell() } if (!args.isHighlighted && !isCellEditMode) { this.setRowFocusType() } this._updateFocusedCellPosition($cell); if (this._allowRowUpdating() && isCellEditMode && column && column.allowEditing) { this._isNeedFocus = false; this._isHiddenFocus = false } else { $cell = this._getFocusedCell(); var $target = event && renderer_1.default(event.target).closest(NON_FOCUSABLE_ELEMENTS_SELECTOR + ", td"); var skipFocusEvent = $target && $target.not($cell).is(NON_FOCUSABLE_ELEMENTS_SELECTOR); var isEditor = !!column && !column.command && $cell.hasClass(EDITOR_CELL_CLASS); var isDisabled = !isEditor && (!args.isHighlighted || skipFocusEvent); this._focus($cell, isDisabled, skipFocusEvent) } } else { this.setRowFocusType(); this.setFocusedRowIndex(args.prevRowIndex); if (this._editingController.isEditing() && isCellEditMode) { this._closeEditCell() } } }, _allowRowUpdating: function() { var rowIndex = this.getVisibleRowIndex(); var row = this._dataController.items()[rowIndex]; return this._editingController.allowUpdating({ row: row }, "click") }, focus: function(element) { var activeElementSelector; var focusedRowEnabled = this.option("focusedRowEnabled"); var isHighlighted = this._isCellElement(renderer_1.default(element)); if (!element) { activeElementSelector = ".dx-datagrid-rowsview .dx-row[tabindex]"; if (!focusedRowEnabled) { activeElementSelector += ", .dx-datagrid-rowsview .dx-row > td[tabindex]" } element = this.component.$element().find(activeElementSelector).first() } element && this._focusElement(renderer_1.default(element), isHighlighted) }, getFocusedView: function() { return this._focusedView }, setupFocusedView: function() { if (this.isKeyboardEnabled() && !type_1.isDefined(this._focusedView)) { this._focusView() } }, _focusElement: function($element, isHighlighted) { var rowsViewElement = renderer_1.default(this._getRowsViewElement()); var $focusedView = $element.closest(rowsViewElement); var isRowFocusType = this.isRowFocusType(); var args = {}; if (!$focusedView.length || this._isCellElement($element) && !this._isCellValid($element)) { return } this._focusView(); this._isNeedFocus = true; this._isNeedScroll = true; if (this._isCellElement($element) || isGroupRow($element)) { this.setCellFocusType(); args = this._fireFocusChangingEvents(null, $element, false, isHighlighted); $element = args.$newCellElement; if (isRowFocusType && !args.isHighlighted) { this.setRowFocusType() } } if (!args.cancel) { this._focus($element, !args.isHighlighted); this._focusInteractiveElement($element) } }, _getFocusedViewByElement: function($element) { var view = this.getFocusedView(); var $view = view && renderer_1.default(view.element()); return $element && 0 !== $element.closest($view).length }, _focusView: function() { this._focusedView = this.getView("rowsView") }, _resetFocusedView: function() { this.setRowFocusType(); this._focusedView = null }, _focusInteractiveElement: function($cell, isLast) { if (!$cell) { return } var $focusedElement = this._getInteractiveElement($cell, isLast); this._testInteractiveElement = $focusedElement; module_utils_1.default.focusAndSelectElement(this, $focusedElement) }, _focus: function($cell, disableFocus, skipFocusEvent) { var $row = $cell && !$cell.hasClass(ROW_CLASS) ? $cell.closest("." + ROW_CLASS) : $cell; if ($row && isNotFocusedRow($row)) { return } var focusedView = this._focusedView; var $focusViewElement = focusedView && focusedView.element(); var $focusElement; this._isHiddenFocus = disableFocus; var isRowFocus = isGroupRow($row) || this.isRowFocusType(); if (isRowFocus) { $focusElement = $row; if (focusedView) { this.setFocusedRowIndex(this._getRowIndex($row)) } } else if (this._isCellElement($cell)) { $focusElement = $cell; this._updateFocusedCellPosition($cell) } if ($focusElement) { if ($focusViewElement) { $focusViewElement.find(".dx-row[tabindex], .dx-row > td[tabindex]").not($focusElement).removeClass(CELL_FOCUS_DISABLED_CLASS).removeAttr("tabindex") } events_engine_1.default.one($focusElement, "blur", (function(e) { if (e.relatedTarget) { $focusElement.removeClass(CELL_FOCUS_DISABLED_CLASS) } })); if (!skipFocusEvent) { this._applyTabIndexToElement($focusElement); events_engine_1.default.trigger($focusElement, "focus") } if (disableFocus) { $focusElement.addClass(CELL_FOCUS_DISABLED_CLASS); if (isRowFocus) { $cell.addClass(CELL_FOCUS_DISABLED_CLASS) } } else { this._editorFactory.focus($focusElement) } } }, _updateFocus: function(isRenderView) { var _this = this; this._updateFocusTimeout = setTimeout((function() { var editingController = _this._editingController; var isCellEditMode = editingController.getEditMode() === EDIT_MODE_CELL; var isBatchEditMode = editingController.getEditMode() === EDIT_MODE_BATCH; if (isCellEditMode && editingController.hasChanges() || isBatchEditMode && editingController.isNewRowInEditMode()) { editingController._focusEditingCell(); return } var $cell = _this._getFocusedCell(); var isEditing = editingController.isEditing(); if ($cell && !(_this._isMasterDetailCell($cell) && !_this._isRowEditMode())) { if (_this._hasSkipRow($cell.parent())) { var direction = _this._focusedCellPosition && _this._focusedCellPosition.rowIndex > 0 ? "upArrow" : "downArrow"; $cell = _this._getNextCell(direction) } if (isElementDefined($cell)) { if ($cell.is("td") || $cell.hasClass(_this.addWidgetPrefix(EDIT_FORM_ITEM_CLASS))) { var isCommandCell = $cell.is(COMMAND_CELL_SELECTOR); var $focusedElementInsideCell = $cell.find(":focus"); var isFocusedElementDefined = isElementDefined($focusedElementInsideCell); if ((isRenderView || !isCommandCell) && _this._editorFactory.focus()) { if (isCommandCell && isFocusedElementDefined) { module_utils_1.default.focusAndSelectElement(_this, $focusedElementInsideCell); return }!isFocusedElementDefined && _this._focus($cell) } else if (!isFocusedElementDefined && (_this._isNeedFocus || _this._isHiddenFocus)) { _this._focus($cell, _this._isHiddenFocus) } if (isEditing) { _this._focusInteractiveElement.bind(_this)($cell) } } else { events_engine_1.default.trigger($cell, "focus") } } } })) }, _getFocusedCell: function() { return renderer_1.default(this._getCell(this._focusedCellPosition)) }, _updateFocusedCellPositionByTarget: function(target) { var _a; var elementType = this._getElementType(target); if ("row" === elementType && type_1.isDefined(null === (_a = this._focusedCellPosition) || void 0 === _a ? void 0 : _a.columnIndex)) { var $row = renderer_1.default(target); this._focusedView && isGroupRow($row) && this.setFocusedRowIndex(this._getRowIndex($row)) } else { this._updateFocusedCellPosition(this._getC