UNPKG

ag-grid

Version:

Advanced Data Grid / Data Table supporting Javascript / React / AngularJS / Web Components

243 lines (242 loc) 12.4 kB
/** * ag-grid - Advanced Data Grid / Data Table supporting Javascript / React / AngularJS / Web Components * @version v18.1.2 * @link http://www.ag-grid.com/ * @license MIT */ "use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; Object.defineProperty(exports, "__esModule", { value: true }); var context_1 = require("../context/context"); var gridCell_1 = require("../entities/gridCell"); var constants_1 = require("../constants"); var mouseEventService_1 = require("./mouseEventService"); var paginationProxy_1 = require("../rowModels/paginationProxy"); var focusedCellController_1 = require("../focusedCellController"); var utils_1 = require("../utils"); var animationFrameService_1 = require("../misc/animationFrameService"); var columnController_1 = require("../columnController/columnController"); var gridOptionsWrapper_1 = require("../gridOptionsWrapper"); var NavigationService = (function () { function NavigationService() { this.timeLastPageEventProcessed = 0; } NavigationService.prototype.init = function () { this.scrollWidth = this.gridOptionsWrapper.getScrollbarWidth(); }; NavigationService.prototype.registerGridComp = function (gridPanel) { this.gridPanel = gridPanel; }; NavigationService.prototype.handlePageScrollingKey = function (event) { var key = event.which || event.keyCode; var alt = event.altKey; var ctrl = event.ctrlKey; var currentCell = this.mouseEventService.getGridCellForEvent(event).getGridCellDef(); if (!currentCell) { return false; } var processed = false; switch (key) { case constants_1.Constants.KEY_PAGE_HOME: case constants_1.Constants.KEY_PAGE_END: // handle home and end when ctrl & alt are NOT pressed if (!ctrl && !alt) { this.onHomeOrEndKey(key); processed = true; } break; case constants_1.Constants.KEY_LEFT: case constants_1.Constants.KEY_RIGHT: // handle left and right when ctrl is pressed only if (ctrl && !alt) { this.onCtrlLeftOrRight(key, currentCell); processed = true; } break; case constants_1.Constants.KEY_UP: case constants_1.Constants.KEY_DOWN: // handle up and down when ctrl is pressed only if (ctrl && !alt) { this.onCtrlUpOrDown(key, currentCell); processed = true; } break; case constants_1.Constants.KEY_PAGE_DOWN: // handle page up and page down when ctrl & alt are NOT pressed if (!ctrl && !alt) { this.onPageDown(currentCell); processed = true; } break; case constants_1.Constants.KEY_PAGE_UP: // handle page up and page down when ctrl & alt are NOT pressed if (!ctrl && !alt) { this.onPageUp(currentCell); processed = true; } break; } if (processed) { event.preventDefault(); } return processed; }; // the page up/down keys caused a problem, in that if the user // held the page up/down key down, lots of events got generated, // which clogged up the event queue (as they take time to process) // which in turn froze the grid. Logic below makes sure we wait 100ms // between processing the page up/down events, so when user has finger // held down on key, we ignore page up/down events until 100ms has passed, // which effectively empties the queue of page up/down events. NavigationService.prototype.isTimeSinceLastPageEventToRecent = function () { var now = new Date().getTime(); var diff = now - this.timeLastPageEventProcessed; return (diff < 100); }; NavigationService.prototype.setTimeLastPageEventProcessed = function () { this.timeLastPageEventProcessed = new Date().getTime(); }; NavigationService.prototype.onPageDown = function (gridCell) { if (this.isTimeSinceLastPageEventToRecent()) { return; } var scrollPosition = this.gridPanel.getVScrollPosition(); var pixelsInOnePage = scrollPosition.bottom - scrollPosition.top; if (this.gridPanel.isHorizontalScrollShowing()) { pixelsInOnePage -= this.scrollWidth; } var pagingPixelOffset = this.paginationProxy.getPixelOffset(); var currentPageBottomPixel = scrollPosition.top + pixelsInOnePage; var currentPageBottomRow = this.paginationProxy.getRowIndexAtPixel(currentPageBottomPixel + pagingPixelOffset); var scrollIndex = currentPageBottomRow; var currentCellPixel = this.paginationProxy.getRow(gridCell.rowIndex).rowTop; var nextCellPixel = currentCellPixel + pixelsInOnePage - pagingPixelOffset; var focusIndex = this.paginationProxy.getRowIndexAtPixel(nextCellPixel + pagingPixelOffset); var pageLastRow = this.paginationProxy.getPageLastRow(); if (focusIndex > pageLastRow) { focusIndex = pageLastRow; } if (scrollIndex > pageLastRow) { scrollIndex = pageLastRow; } this.navigateTo(scrollIndex, 'top', null, focusIndex, gridCell.column); this.setTimeLastPageEventProcessed(); }; NavigationService.prototype.onPageUp = function (gridCell) { if (this.isTimeSinceLastPageEventToRecent()) { return; } var scrollPosition = this.gridPanel.getVScrollPosition(); var pixelsInOnePage = scrollPosition.bottom - scrollPosition.top; if (this.gridPanel.isHorizontalScrollShowing()) { pixelsInOnePage -= this.scrollWidth; } var pagingPixelOffset = this.paginationProxy.getPixelOffset(); var currentPageTopPixel = scrollPosition.top; var currentPageTopRow = this.paginationProxy.getRowIndexAtPixel(currentPageTopPixel + pagingPixelOffset); var scrollIndex = currentPageTopRow; var currentRowNode = this.paginationProxy.getRow(gridCell.rowIndex); var nextCellPixel = currentRowNode.rowTop + currentRowNode.rowHeight - pixelsInOnePage - pagingPixelOffset; var focusIndex = this.paginationProxy.getRowIndexAtPixel(nextCellPixel + pagingPixelOffset); var firstRow = this.paginationProxy.getPageFirstRow(); if (focusIndex < firstRow) { focusIndex = firstRow; } if (scrollIndex < firstRow) { scrollIndex = firstRow; } this.navigateTo(scrollIndex, 'bottom', null, focusIndex, gridCell.column); this.setTimeLastPageEventProcessed(); }; // common logic to navigate. takes parameters: // scrollIndex - what row to vertically scroll to // scrollType - what position to put scroll index ie top/bottom // scrollColumn - what column to horizontally scroll to // focusIndex / focusColumn - for page up / down, we want to scroll to one row/column, but focus another NavigationService.prototype.navigateTo = function (scrollIndex, scrollType, scrollColumn, focusIndex, focusColumn) { if (utils_1._.exists(scrollColumn)) { this.gridPanel.ensureColumnVisible(scrollColumn); } if (utils_1._.exists(scrollIndex)) { this.gridPanel.ensureIndexVisible(scrollIndex, scrollType); } // make sure the cell is rendered, needed if we are to focus this.animationFrameService.flushAllFrames(); // if we don't do this, the range will be left on the last cell, which will leave the last focused cell // highlighted. this.focusedCellController.setFocusedCell(focusIndex, focusColumn, null, true); if (this.rangeController) { var gridCell = new gridCell_1.GridCell({ rowIndex: focusIndex, floating: null, column: focusColumn }); this.rangeController.setRangeToCell(gridCell); } }; // ctrl + up/down will bring focus to same column, first/last row. no horizontal scrolling. NavigationService.prototype.onCtrlUpOrDown = function (key, gridCell) { var upKey = key === constants_1.Constants.KEY_UP; var rowIndexToScrollTo = upKey ? 0 : this.paginationProxy.getPageLastRow(); this.navigateTo(rowIndexToScrollTo, null, gridCell.column, rowIndexToScrollTo, gridCell.column); }; // ctrl + left/right will bring focus to same row, first/last cell. no vertical scrolling. NavigationService.prototype.onCtrlLeftOrRight = function (key, gridCell) { var leftKey = key === constants_1.Constants.KEY_LEFT; var allColumns = this.columnController.getAllDisplayedColumns(); var columnToSelect = leftKey ? allColumns[0] : allColumns[allColumns.length - 1]; this.navigateTo(gridCell.rowIndex, null, columnToSelect, gridCell.rowIndex, columnToSelect); }; // home brings focus to top left cell, end brings focus to bottom right, grid scrolled to bring // same cell into view (which means either scroll all the way up, or all the way down). NavigationService.prototype.onHomeOrEndKey = function (key) { var homeKey = key === constants_1.Constants.KEY_PAGE_HOME; var allColumns = this.columnController.getAllDisplayedColumns(); var columnToSelect = homeKey ? allColumns[0] : allColumns[allColumns.length - 1]; var rowIndexToScrollTo = homeKey ? 0 : this.paginationProxy.getPageLastRow(); this.navigateTo(rowIndexToScrollTo, null, columnToSelect, rowIndexToScrollTo, columnToSelect); }; __decorate([ context_1.Autowired('mouseEventService'), __metadata("design:type", mouseEventService_1.MouseEventService) ], NavigationService.prototype, "mouseEventService", void 0); __decorate([ context_1.Autowired('paginationProxy'), __metadata("design:type", paginationProxy_1.PaginationProxy) ], NavigationService.prototype, "paginationProxy", void 0); __decorate([ context_1.Autowired('focusedCellController'), __metadata("design:type", focusedCellController_1.FocusedCellController) ], NavigationService.prototype, "focusedCellController", void 0); __decorate([ context_1.Autowired('animationFrameService'), __metadata("design:type", animationFrameService_1.AnimationFrameService) ], NavigationService.prototype, "animationFrameService", void 0); __decorate([ context_1.Optional('rangeController'), __metadata("design:type", Object) ], NavigationService.prototype, "rangeController", void 0); __decorate([ context_1.Autowired('columnController'), __metadata("design:type", columnController_1.ColumnController) ], NavigationService.prototype, "columnController", void 0); __decorate([ context_1.Autowired('gridOptionsWrapper'), __metadata("design:type", gridOptionsWrapper_1.GridOptionsWrapper) ], NavigationService.prototype, "gridOptionsWrapper", void 0); __decorate([ context_1.PostConstruct, __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", void 0) ], NavigationService.prototype, "init", null); NavigationService = __decorate([ context_1.Bean('navigationService') ], NavigationService); return NavigationService; }()); exports.NavigationService = NavigationService;