How do I scroll an ngGrid to show the current selection?
Asked Answered
A

4

10

I'm setting the selection of my ngGrid from JavaScript, calling gridOptions.selectItem(). I have multiSelect set to false, so there is only ever one row selected. I'd like the ngGrid to automatically scroll to show the newly selected row, but I don't know how to do this: can anyone help, please?

On a related topic: can I disable row selection by mouse click? If so, how?

Edited to add

I'd also like to disable keyboard navigation of the selected row, if possible.

What worked:

AardVark71's answer worked. I discovered that ngGrid defines a property ngGrid on the gridOptions variable which holds a reference to the grid object itself. The necessary functions are exposed via properties of this object:

$scope.gridOptions.selectItem(itemNumber, true);
$scope.gridOptions.ngGrid.$viewport.scrollTop(Math.max(0, (itemNumber - 6))*$scope.gridOptions.ngGrid.config.rowHeight);

My grid is fixed at 13 rows high, and my logic attempts to make the selected row appear in the middle of the grid.

I'd still like to disable mouse & keyboard changes to the selection, if possible.

What also worked:

This is probably closer to the 'Angular Way' and achieves the same end:

// This $watch scrolls the ngGrid to show a newly-selected row as close to the middle row as possible
$scope.$watch('gridOptions.ngGrid.config.selectedItems', function (newValue, oldValue, scope) {
            if (newValue != oldValue && newValue.length > 0) {
                var rowIndex = scope.gridOptions.ngGrid.data.indexOf(newValue[0]);
                scope.gridOptions.ngGrid.$viewport.scrollTop(Math.max(0, (rowIndex - 6))*scope.gridOptions.ngGrid.config.rowHeight);
            }
        }, true);

although the effect when a row is selected by clicking on it can be a bit disconcerting.

Adiathermancy answered 28/8, 2013 at 12:5 Comment(3)
Can you show code of what you got so far? It sounds like you can make use of the scrollTop method. See also github.com/angular-ui/ng-grid/issues/183 and the following plunker from @bryan-watts run.plnkr.co/plunks/oyIlX9Homogenous
OK I've got it working, thanks to this tip! There is an undocumented ngGrid property which is added to the gridOptions property that holds a reference to the actual grid itself. The function call to scroll the viewport is then $scope.gridOptions.ngGrid.$viewport.scrollTop(rowNumber*$scope.gridOptions.ngGrid.config.rowHeight) AardVark71 - Please update this to an Answer & I'll credit you: many thanks!Adiathermancy
Glad it worked for you, I'll rephrase it as an answerHomogenous
H
14

It sounds like you can make use of the scrollTop method for the scrolling.

See also http://github.com/angular-ui/ng-grid/issues/183 and the following plunker from @bryan-watts http://plnkr.co/edit/oyIlX9?p=preview

An example how this could work would be as follows:

function focusRow(rowToSelect) {
  $scope.gridOptions.selectItem(rowToSelect, true);
  var grid = $scope.gridOptions.ngGrid;
  grid.$viewport.scrollTop(grid.rowMap[rowToSelect] * grid.config.rowHeight);
}


edit:

For the second part of your question "disabling the mouse and keyboard events of the selected rows" it might be best to start a new Question. Sounds like you want to set your enableRowSelection dynamically to false? No idea if that's possible.

Homogenous answered 29/8, 2013 at 14:40 Comment(2)
Yes, you can set it dynamically, like this: $scope.gridOptions.ngGrid.config.enableRowSelection = true;. However it doesn't have quite the right effect. If I set enableRowSelection = false; in the initial gridOptions, mouse clicks are disabled and remain disabled even when the option subsequently set to true, but the up/down arrow keys remain active. Clearing the option also disables the style change for the selected row, which is OK for me.Adiathermancy
this solution doesnt work if you activate a filter on the grid. anyone have an idea about that?Chickamauga
P
1

I believe I was looking for the same behavior from ng-grid as yourself. The following function added to your gridOptions object will both disallow selection via the arrow keys (but allow it if shift or ctrl is held down) and scroll the window when moving down the list using the arrow keys so that the currently selected row is always visible:

beforeSelectionChange: function(rowItem, event){
    if(!event.ctrlKey && !event.shiftKey && event.type != 'click'){
      var grid = $scope.gridOptions.ngGrid;
      grid.$viewport.scrollTop(rowItem.offsetTop - (grid.config.rowHeight * 2));
      angular.forEach($scope.myData, function(data, index){
        $scope.gridOptions.selectRow(index, false);
      });
    }
    return true;
  },

edit: here is a plunkr: http://plnkr.co/edit/xsY6W9u7meZsTJn4p1to?p=preview

Hope that helps!

Paulenepauletta answered 6/10, 2014 at 18:28 Comment(0)
N
1

I found the accepted answer above is not working with the latest version of ui-grid (v4.0.4 - 2017-04-04).

Here is the code I use:

$scope.gridApi.core.scrollTo(vm.gridOptions.data[indexToSelect]);

In gripOptions, you need to register the gridApi in onRegisterApi.

onRegisterApi: function (gridApi) {
   $scope.gridApi = gridApi;
},
Noncombatant answered 16/5, 2017 at 23:1 Comment(1)
It's been a long while since I encountered this issue - a lot of versions since then! Thanks for keeping the answer list current.Adiathermancy
V
0
  var grid = $scope.gridOptions.ngGrid;
    var aggRowOffsetTop = 0;
    var containerHeight = $(".gridStyle").height() - 40;
    angular.forEach(grid.rowFactory.parsedData, function(row) {
        if(row.entity.isAggRow) {
            aggRowOffsetTop = row.offsetTop;
        }
        if(row.entity.id == $scope.selectedId) {
            if((row.offsetTop - aggRowOffsetTop) < containerHeight) {
                 grid.$viewport.scrollTop(aggRowOffsetTop);
            } else {
                grid.$viewport.scrollTop(row.offsetTop);
            }
        } 
    });
Vaporing answered 26/12, 2013 at 13:3 Comment(1)
you should put some description alsoProbability

© 2022 - 2024 — McMap. All rights reserved.