UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

1,072 lines (1,057 loc) • 95.9 kB
/** * DevExtreme (cjs/ui/grid_core/ui.grid_core.keyboard_navigation.js) * Version: 21.1.4 * Build date: Mon Jun 21 2021 * * Copyright (c) 2012 - 2021 Developer Express Inc. ALL RIGHTS RESERVED * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/ */ "use strict"; function _typeof(obj) { if ("function" === typeof Symbol && "symbol" === typeof Symbol.iterator) { _typeof = function(obj) { return typeof obj } } else { _typeof = function(obj) { return obj && "function" === typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj } } return _typeof(obj) } exports.keyboardNavigationModule = void 0; var _renderer = _interopRequireDefault(require("../../core/renderer")); var _dom_adapter = _interopRequireDefault(require("../../core/dom_adapter")); var _events_engine = _interopRequireDefault(require("../../events/core/events_engine")); var _uiGrid_core = _interopRequireDefault(require("./ui.grid_core.modules")); var _uiGrid_core2 = _interopRequireDefault(require("./ui.grid_core.utils")); var _type = require("../../core/utils/type"); var _array = require("../../core/utils/array"); var _selectors = require("../widget/selectors"); var _index = require("../../events/utils/index"); var _pointer = _interopRequireDefault(require("../../events/pointer")); var _click = require("../../events/click"); var _common = require("../../core/utils/common"); var accessibility = _interopRequireWildcard(require("../shared/accessibility")); var _browser = _interopRequireDefault(require("../../core/utils/browser")); var _short = require("../../events/short"); var _devices = _interopRequireDefault(require("../../core/devices")); function _getRequireWildcardCache(nodeInterop) { if ("function" !== typeof WeakMap) { return null } var cacheBabelInterop = new WeakMap; var cacheNodeInterop = new WeakMap; return (_getRequireWildcardCache = function(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop })(nodeInterop) } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj } if (null === obj || "object" !== _typeof(obj) && "function" !== typeof obj) { return { default: obj } } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj) } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if ("default" !== key && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc) } else { newObj[key] = obj[key] } } } newObj.default = obj; if (cache) { cache.set(obj, newObj) } return newObj } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj } } 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-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"; 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 isCellElement($element) { return $element.length && "TD" === $element[0].tagName } function isEditorCell(that, $cell) { return !that._isRowEditMode() && $cell && !$cell.hasClass(COMMAND_SELECT_CLASS) && $cell.hasClass(EDITOR_CELL_CLASS) } function isElementDefined($element) { return (0, _type.isDefined)($element) && $element.length > 0 } function isMobile() { return "desktop" !== _devices.default.current().deviceType } function isCellInHeaderRow($cell) { return !!$cell.parent(".".concat(HEADER_ROW_CLASS)).length } function isFixedColumnIndexOffsetRequired(that, column) { var rtlEnabled = that.option("rtlEnabled"); var result = false; if (rtlEnabled) { result = !("right" === column.fixedPosition || (0, _type.isDefined)(column.command) && !(0, _type.isDefined)(column.fixedPosition)) } else { result = !(!(0, _type.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 = _uiGrid_core.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 _this2 = this; var rowsView = this.getView("rowsView"); var rowsViewFocusHandler = function(event) { var $element = (0, _renderer.default)(event.target); var isRelatedTargetInRowsView = (0, _renderer.default)(event.relatedTarget).closest(rowsView.element()).length; var isCommandButton = $element.hasClass("dx-link"); if (isCommandButton && !isRelatedTargetInRowsView && _this2._isEventInCurrentGrid(event)) { var $focusedCell = _this2._getFocusedCell(); $focusedCell = !isElementDefined($focusedCell) ? rowsView.getCellElements(0).filter("[tabindex]").eq(0) : $focusedCell; if (!$element.closest($focusedCell).length) { event.preventDefault(); _events_engine.default.trigger($focusedCell, "focus") } } }; rowsView.renderCompleted.add((function(e) { var $rowsView = rowsView.element(); var isFullUpdate = !e || "refresh" === e.changeType; var isFocusedViewCorrect = _this2._focusedView && _this2._focusedView.name === rowsView.name; var needUpdateFocus = false; var isAppend = e && ("append" === e.changeType || "prepend" === e.changeType); var $focusedElement = (0, _renderer.default)(":focus"); var isFocusedElementCorrect = !$focusedElement.length || $focusedElement.closest($rowsView).length || _browser.default.msie && $focusedElement.is("body"); _events_engine.default.off($rowsView, "focusin", rowsViewFocusHandler); _events_engine.default.on($rowsView, "focusin", rowsViewFocusHandler); _this2._initPointerEventHandler(); _this2._initKeyDownHandler(); _this2._setRowsViewAttributes(); if (isFocusedViewCorrect && isFocusedElementCorrect) { needUpdateFocus = _this2._isNeedFocus ? !isAppend : _this2._isHiddenFocus && isFullUpdate; needUpdateFocus && _this2._updateFocus(true) } })) }, _initDocumentHandlers: function() { var _this3 = this; var document = _dom_adapter.default.getDocument(); this._documentClickHandler = this.createAction((function(e) { var $target = (0, _renderer.default)(e.event.target); var isCurrentRowsViewClick = _this3._isEventInCurrentGrid(e.event) && $target.closest(".".concat(_this3.addWidgetPrefix(ROWS_VIEW_CLASS))).length; var isEditorOverlay = $target.closest(".".concat(DROPDOWN_EDITOR_OVERLAY_CLASS)).length; var columnsResizerController = _this3.getController("columnsResizer"); var isColumnResizing = !!columnsResizerController && columnsResizerController.isResizing(); if (!isCurrentRowsViewClick && !isEditorOverlay && !isColumnResizing) { var targetInsideFocusedView = _this3._focusedView ? $target.parents().filter(_this3._focusedView.element()).length > 0 : false; !targetInsideFocusedView && _this3._resetFocusedCell(true); _this3._resetFocusedView() } })); _events_engine.default.on(document, (0, _index.addNamespace)(_pointer.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.default.down : _click.name; var clickSelector = ".".concat(ROW_CLASS, " > td, .").concat(ROW_CLASS); var $rowsView = this._getRowsViewElement(); if (!(0, _type.isDefined)(this._pointerEventAction)) { this._pointerEventAction = this.createAction(this._pointerEventHandler) } _events_engine.default.off($rowsView, (0, _index.addNamespace)(pointerEventName, "dxDataGridKeyboardNavigation"), this._pointerEventAction); _events_engine.default.on($rowsView, (0, _index.addNamespace)(pointerEventName, "dxDataGridKeyboardNavigation"), clickSelector, this._pointerEventAction) }, _initKeyDownHandler: function() { var _this4 = this; var $rowsView = this._getRowsViewElement(); _short.keyboard.off(this._keyDownListener); this._keyDownListener = _short.keyboard.on($rowsView, null, (function(e) { return _this4._keyDownHandler(e) })) }, dispose: function() { this.callBase(); this._resetFocusedView(); _short.keyboard.off(this._keyDownListener); _events_engine.default.off(_dom_adapter.default.getDocument(), (0, _index.addNamespace)(_pointer.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 isEditing = this._editingController.isEditing(); var needStopPropagation = true; var originalEvent = e.originalEvent; var isHandled = this._processOnKeyDown(e); if (originalEvent.isDefaultPrevented()) { return } this._isNeedFocus = true; this._isNeedScroll = true; this._updateFocusedCellPositionByTarget(originalEvent.target); if (!isHandled) { switch (e.keyName) { case "leftArrow": case "rightArrow": this._leftRightKeysHandler(e, isEditing); break; case "upArrow": case "downArrow": if (e.ctrl) { accessibility.selectView("rowsView", this, originalEvent) } else { this._upDownKeysHandler(e, isEditing) } break; case "pageUp": case "pageDown": this._pageUpDownKeyHandler(e); break; case "space": this._spaceKeyHandler(e, isEditing); break; case "A": if ((0, _index.isCommandKeyPressed)(e.originalEvent)) { this._ctrlAKeyHandler(e, isEditing) } else { this._beginFastEditing(e.originalEvent) } break; case "tab": this._tabKeyHandler(e, isEditing); break; case "enter": this._enterKeyHandler(e, isEditing); break; case "escape": this._escapeKeyHandler(e, isEditing); break; case "F": if ((0, _index.isCommandKeyPressed)(e.originalEvent)) { this._ctrlFKeyHandler(e) } else { this._beginFastEditing(e.originalEvent) } break; case "F2": this._f2KeyHandler(); break; case "del": case "backspace": if (this._isFastEditingAllowed() && !this._isFastEditingStarted()) { this._beginFastEditing(originalEvent, true) } break; default: if (!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 _this5 = this; setTimeout((function() { _this5._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 rowIndex = this._focusedCellPosition.rowIndex; 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 isEditingNavigationMode = this._isFastEditingStarted(); var allowNavigate = (!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 = $row.outerHeight(); 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 && scrollable._container().height() < scrollable.$content().height()) { this._scrollBy(0, scrollable._container().height() * pageStep); eventArgs.originalEvent.preventDefault() } }, _spaceKeyHandler: function(eventArgs, isEditing) { var rowIndex = this.getVisibleRowIndex(); var $target = (0, _renderer.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() } } else { 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 = (0, _type.isDefined)(this._focusedCellPosition) && !(0, _type.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 }(0, _renderer.default)(focusedViewElement).addClass(FOCUS_STATE_CLASS); if (editingOptions && eventTarget && !isOriginalHandlerRequired) { if ((0, _renderer.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() - (0, _renderer.default)(rowsView.element()).width() : 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 ((0, _type.isDefined)(nextColumnIndex) && (0, _type.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 && $currentCell.outerWidth(); 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 = !row || "data" === row.rowType; isEditingAllowed = editingController.allowUpdating({ row: row }) ? _isDataRow : 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 && (0, _renderer.default)(eventTarget).hasClass(ROW_CLASS)) { this._updateFocusedCellPosition($cell) } elementType = this._getElementType(eventTarget); if (this.isRowFocusType()) { this.setCellFocusType(); if ("row" === elementType && isDataRow((0, _renderer.default)(eventTarget))) { eventTarget = this.getFirstValidCellInRow((0, _renderer.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.default.trigger((0, _renderer.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 = (0, _renderer.default)(event.currentTarget); var rowsView = this.getView("rowsView"); var focusedViewElement = rowsView && rowsView.element(); var $parent = $target.parent(); var isInteractiveElement = (0, _renderer.default)(event.target).is(INTERACTIVE_ELEMENTS_SELECTOR); var isRevertButton = !!(0, _renderer.default)(event.target).closest(".".concat(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) ? (0, _renderer.default)(event.target) : $target; this._focusView(); (0, _renderer.default)(focusedViewElement).removeClass(FOCUS_STATE_CLASS); if ($parent.hasClass(FREESPACE_ROW_CLASS)) { this._updateFocusedCellPosition($target); this._applyTabIndexToElement(this._focusedView.element()); this._focusedView.focus() } 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 { var $target = event && (0, _renderer.default)(event.target).closest(INTERACTIVE_ELEMENTS_SELECTOR + ", td"); var isInteractiveTarget = $target && $target.not($cell).is(INTERACTIVE_ELEMENTS_SELECTOR); var isEditor = !!column && !column.command && $cell.hasClass(EDITOR_CELL_CLASS); var isDisabled = !isEditor && (!args.isHighlighted || isInteractiveTarget); this._focus($cell, isDisabled, isInteractiveTarget) } } else { this.setRowFocusType(); this.setFocusedRowIndex(args.prevRowIndex); $cell = this._getFocusedCell(); 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 = isCellElement((0, _renderer.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((0, _renderer.default)(element), isHighlighted) }, getFocusedView: function() { return this._focusedView }, setupFocusedView: function() { if (this.isKeyboardEnabled() && !(0, _type.isDefined)(this._focusedView)) { this._focusView() } }, _focusElement: function($element, isHighlighted) { var rowsViewElement = (0, _renderer.default)(this._getRowsViewElement()); var $focusedView = $element.closest(rowsViewElement); var isRowFocusType = this.isRowFocusType(); var args = {}; if (!$focusedView.length || isCellElement($element) && !this._isCellValid($element)) { return } this._focusView(); this._isNeedFocus = true; this._isNeedScroll = true; if (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 && (0, _renderer.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); _uiGrid_core2.default.focusAndSelectElement(this, $focusedElement) }, _focus: function($cell, disableFocus, isInteractiveElement) { var $row = $cell && !$cell.hasClass(ROW_CLASS) ? $cell.closest(".".concat(ROW_CLASS)) : $cell; if ($row && isNotFocusedRow($row)) { return } var focusedView = this._focusedView; var $focusViewElement = focusedView && focusedView.element(); var $focusElement; this._isHiddenFocus = disableFocus; if (isGroupRow($row) || this.isRowFocusType()) { $focusElement = $row; if (focusedView) { this.setFocusedRowIndex(this._getRowIndex($row)) } } else if (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.default.one($focusElement, "blur", (function(e) { if (e.relatedTarget) { $focusElement.removeClass(CELL_FOCUS_DISABLED_CLASS) } })); if (!isInteractiveElement) { this._applyTabIndexToElement($focusElement); _events_engine.default.trigger($focusElement, "focus") } if (disableFocus) { $focusElement.addClass(CELL_FOCUS_DISABLED_CLASS) } else { this._editorFactory.focus($focusElement) } } }, _updateFocus: function(isRenderView) { var _this6 = this; this._updateFocusTimeout = setTimeout((function() { var editingController = _this6._editingController; var isCellEditMode = editingController.getEditMode() === EDIT_MODE_CELL; if (isCellEditMode && editingController.hasChanges()) { editingController._focusEditingCell(); return } var $cell = _this6._getFocusedCell(); var isEditing = editingController.isEditing(); if ($cell && !(_this6._isMasterDetailCell($cell) && !_this6._isRowEditMode())) { if (_this6._hasSkipRow($cell.parent())) { var direction = _this6._focusedCellPosition && _this6._focusedCellPosition.rowIndex > 0 ? "upArrow" : "downArrow"; $cell = _this6._getNextCell(direction) } if (isElementDefined($cell)) { if (isRenderView && !isEditing && _this6._checkCellOverlapped($cell)) { return } if ($cell.is("td") || $cell.hasClass(_this6.addWidgetPrefix(EDIT_FORM_ITEM_CLASS))) { var isCommandCell = $cell.is(COMMAND_CELL_SELECTOR); var $focusedElementInsideCell = $cell.find(":focus"); var isFocusedElementDefined = isElementDefined($focusedElementInsideCell); if ((isRenderView || !isCommandCell) && _this6._editorFactory.focus()) { if (isCommandCell && isFocusedElementDefined) { _uiGrid_core2.default.focusAndSelectElement(_this6, $focusedElementInsideCell); return }!isFocusedElementDefined && _this6._focus($cell) } else if (!isFocusedElementDefined && (_this6._isNeedFocus || _this6._isHiddenFocus)) { _this6._focus($cell, _this6._isHiddenFocus) } if (isEditing) { _this6._focusInteractiveElement.bind(_this6)($cell) } } else { _events_engine.default.trigger($cell, "focus") } } } })) }, _checkCellOverlapped: function($cell) { var cellOffset = $cell.offset(); var hasScrollable = this.component.getScrollable && this.component.getScrollable(); var isOverlapped = false; if (hasScrollable) { if (cellOffset.left < 0) { isOverlapped = $cell.width() + cellOffset.left <= 0 } else if (cellOffset.top < 0) { isOverlapped = $cell.height() + cellOffset.top <= 0 } } return isOverlapped }, _getFocusedCell: function() { return (0, _renderer.default)(this._getCell(this._focusedCellPosition)) }, _updateFocusedCellPositionByTarget: function(target) { var _this$_focusedCellPos; var elementType = this._getElementType(target); if ("row" === elementType && (0, _t