From d587c842de4e36801e24067cbb93492b529b8744 Mon Sep 17 00:00:00 2001 From: Paul Lambert Date: Wed, 17 Sep 2014 13:58:15 +1000 Subject: [PATCH] scrollTo method completed on cellNav feature Including unit test extensions, and additions to tutorial 202. --- misc/tutorial/202_cellnav.ngdoc | 28 ++++++-- src/features/cellnav/js/cellnav.js | 66 +++++++++++++++++-- .../cellnav/test/uiGridCellNavService.spec.js | 49 +++++++++++++- 3 files changed, 130 insertions(+), 13 deletions(-) diff --git a/misc/tutorial/202_cellnav.ngdoc b/misc/tutorial/202_cellnav.ngdoc index 2f63d0a2de..3b9a2e382f 100644 --- a/misc/tutorial/202_cellnav.ngdoc +++ b/misc/tutorial/202_cellnav.ngdoc @@ -2,10 +2,14 @@ @name Tutorial: 202 Cell Navigation @description -This grid example uses the ui-grid-cellNav directive to add cell navigation. To enable, you must include the 'ui.grid.cellNav' module and you must include the ui-grid-cellNav directive on your grid element. +This grid example uses the ui-grid-cellNav directive to add cell navigation. To enable, you must include the 'ui.grid.cellNav' +module and you must include the ui-grid-cellNav directive on your grid element. Uses the gridOptions.onRegisterApi callback to register the on_cellNav event and log when the cell is navigated. +Also provides an example of requesting a scroll to a specific row or column programatically - useful for +remembering the state of a page and scrolling back to that position when a user returns. + @example @@ -15,10 +19,15 @@ Uses the gridOptions.onRegisterApi callback to register the on_cellNav event and $scope.gridOptions = {}; $scope.gridOptions.columnDefs = [ - { name: 'id' }, - { name: 'name'}, - { name: 'age', displayName: 'Age (not focusable)', allowCellFocus : false }, - { name: 'address.city' } + { name: 'id', width:'10%' }, + { name: 'name', width:'30%' }, + { name: 'age', displayName: 'Age (not focusable)', allowCellFocus : false, width:'15%' }, + { name: 'address.city', width:'25%' }, + { name: 'phone', width:'30%' }, + { name: 'company', width:'25%' }, + { name: 'email', width:'30%' }, + { name: 'balance', width:'20%' }, + { name: 'guid', width:'40%' } ]; $http.get('/data/500_complex.json') @@ -35,7 +44,11 @@ Uses the gridOptions.onRegisterApi callback to register the on_cellNav event and if(rowCol !== null) { $scope.currentFocused = 'Row Id:' + rowCol.row.entity.id + ' col:' + rowCol.col.colDef.name; } - } + }; + + $scope.scrollTo = function( rowIndex, colIndex ) { + $scope.gridApi.cellNav.scrollTo( $scope, $scope.gridOptions.data[rowIndex], $scope.gridOptions.columnDefs[colIndex]); + }; $scope.gridOptions.onRegisterApi = function(gridApi){ $scope.gridApi = gridApi; @@ -53,6 +66,9 @@ Uses the gridOptions.onRegisterApi callback to register the on_cellNav event and
+ + +

diff --git a/src/features/cellnav/js/cellnav.js b/src/features/cellnav/js/cellnav.js index 8a281d31ff..1448e31780 100644 --- a/src/features/cellnav/js/cellnav.js +++ b/src/features/cellnav/js/cellnav.js @@ -32,6 +32,8 @@ var service = { initializeGrid: function (grid) { + this.grid = grid; + grid.registerColumnBuilder(service.cellNavColumnBuilder); //create variables for state @@ -67,15 +69,13 @@ * @ngdoc function * @name scrollTo * @methodOf ui.grid.cellNav.api:PublicApi - * @description (TODO) brings the row and column into view + * @description brings the specified row and column into view + * @param {object} $scope a scope we can broadcast events from * @param {object} rowEntity gridOptions.data[] array instance to make visible * @param {object} colDef to make visible */ - scrollTo: function (rowEntity, colDef) { - var row = grid.getRow(rowEntity); - if (row !== null) { - //todo: scroll into view - } + scrollTo: function ($scope, rowEntity, colDef) { + service.scrollTo($scope, rowEntity, colDef); }, /** * @ngdoc function @@ -285,6 +285,60 @@ colDef.allowCellFocus = colDef.allowCellFocus === undefined ? true : colDef.allowCellFocus ; return $q.all(promises); + }, + + /** + * @ngdoc method + * @methodOf ui.grid.cellNav.service:uiGridCellNavService + * @name scrollVerticallyTo + * @description Scroll the grid vertically such that the specified + * row is in view + * @param {object} $scope a scope we can broadcast events from + * @param {object} rowEntity gridOptions.data[] array instance to make visible + * @param {object} colDef to make visible + */ + scrollTo: function ($scope, rowEntity, colDef) { + var args = {}; + + if ( rowEntity !== null ){ + var row = this.grid.getRow(rowEntity); + if ( row ) { + args.y = { percentage: row.index / this.grid.rows.length }; + } + } + + if ( colDef !== null ){ + var col = this.grid.getColumn(colDef.name ? colDef.name : colDef.field); + if ( col ) { + args.x = { percentage: this.getLeftWidth(col.index) / this.getLeftWidth(this.grid.columns.length - 1) }; + } + } + + if ( args.y || args.x ){ + $scope.$broadcast(uiGridConstants.events.GRID_SCROLL, args); + } + }, + + + /** + * @ngdoc method + * @methodOf ui.grid.cellNav.service:uiGridCellNavService + * @name getLeftWidth + * @description Get the current drawn width of the columns in the + * grid up to and including the numbered column + * @param {object} colIndex the column to total up to and including + */ + getLeftWidth: function( colIndex ){ + var width = 0; + + if ( !colIndex ){ return; } + + for ( var i=0; i <= colIndex; i++ ){ + if ( this.grid.columns[i].drawnWidth ){ + width += this.grid.columns[i].drawnWidth; + } + } + return width; } }; diff --git a/src/features/cellnav/test/uiGridCellNavService.spec.js b/src/features/cellnav/test/uiGridCellNavService.spec.js index 2af5575319..ba0fcbd264 100644 --- a/src/features/cellnav/test/uiGridCellNavService.spec.js +++ b/src/features/cellnav/test/uiGridCellNavService.spec.js @@ -4,14 +4,16 @@ describe('ui.grid.edit uiGridCellNavService', function () { var grid; var uiGridConstants; var uiGridCellNavConstants; + var $rootScope; beforeEach(module('ui.grid.cellNav')); - beforeEach(inject(function (_uiGridCellNavService_, _gridClassFactory_, $templateCache, _uiGridConstants_, _uiGridCellNavConstants_) { + beforeEach(inject(function (_uiGridCellNavService_, _gridClassFactory_, $templateCache, _uiGridConstants_, _uiGridCellNavConstants_, _$rootScope_) { uiGridCellNavService = _uiGridCellNavService_; gridClassFactory = _gridClassFactory_; uiGridConstants = _uiGridConstants_; uiGridCellNavConstants = _uiGridCellNavConstants_; + $rootScope = _$rootScope_; $templateCache.put('ui-grid/uiGridCell', '
'); @@ -291,4 +293,49 @@ describe('ui.grid.edit uiGridCellNavService', function () { }); + describe('scrollTo', function () { + var evt; + var args; + var $scope; + + beforeEach(function(){ + grid.registerColumnBuilder(uiGridCellNavService.cellNavColumnBuilder); + grid.buildColumns(); + $scope = $rootScope.$new(); + + evt = null; + args = null; + $scope.$on(uiGridConstants.events.GRID_SCROLL, function( receivedEvt, receivedArgs ){ + evt = receivedEvt; + args = receivedArgs; + }); + grid.columns[0].drawnWidth = 100; + grid.columns[1].drawnWidth = 200; + grid.columns[2].drawnWidth = 300; + }); + + it('should request scroll to row and column', function () { + uiGridCellNavService.scrollTo( $scope, grid.options.data[2], grid.columns[1].colDef); + + expect(args).toEqual( { y : { percentage : 2/3 }, x : { percentage : 300/600 } }); + }); + + it('should request scroll to row only', function () { + uiGridCellNavService.scrollTo( $scope, grid.options.data[2], null); + + expect(args).toEqual( { y : { percentage : 2/3 } }); + }); + + it('should request scroll to column only', function () { + uiGridCellNavService.scrollTo( $scope, null, grid.columns[1].colDef); + + expect(args).toEqual( { x : { percentage : 300/600 } }); + }); + + it('should request no scroll as no row or column', function () { + uiGridCellNavService.scrollTo( $scope, null, null ); + + expect(args).toEqual(null); + }); + }); }); \ No newline at end of file