Whats the equivalent for ng-grid's "beforeSelectionChange" in ui-grid?
Asked Answered
P

2

8

In ng-grid, I used to use beforeSelectionChange in the following way:

When the user selects a row, an ajax call is performed. While the ajax call is happenning I set $scope.doingAjaxCall = true, and to prevent the user from changing the selection, I had this in the grid definition:

beforeSelectionChange: function () {
    return !($scope.doingAjaxCall);
},

which locks/freezes the selection if the ajax call is happenning.

Now, in ui-grid (aka ng-grid 3), I don't know whats the equivalent for afterSelectionChange.

In this section of the documentation:
http://ui-grid.info/docs/#/api/ui.grid.selection.api:PublicApi
I see two events:

  • rowSelectionChanges
  • rowSelectionChangedBatch.

These seem to be the equivalent of the old afterSelectionChange

And in this section of the documentation:
http://ui-grid.info/docs/#/api/ui.grid.selection.service:uiGridSelectionService
I see these two methods that seem to be related to the need:

  • raiseSelectionEvent(grid, changedRows, event)
  • decideRaiseSelectionEvent(grid, row, changedRows, event)

But I don't understand how to use them

Important note:
I'm using multiSelect: false (ie: only one row can be selected)

Putnem answered 19/8, 2015 at 16:32 Comment(2)
Too bad there isnt an equivalent. I cant move from ng-grid to ui-grid without thisPutnem
...any news on this? 1 year later?Putnem
A
0

This is a bit of a hack, but it'll get the job done until you find a better solution. Here's a working plunker.

I assume you use rowSelectionChanged to perform the AJAX call and toggle doingAjaxCall.

gridApi.selection.on.rowSelectionChanged($scope, function(row) {
  $log.log('Row ' + row.entity.id + ' selected: ' + row.isSelected);

  $log.log('  Simulating ajax call...');
  $scope.doingAjaxCall = true;
  $timeout(function() {
    $log.log('  ...done with ajax call');
    $scope.doingAjaxCall = false;
  }, 2000);
});

Then, modify the template that ui-grid uses for the select buttons.

$templateCache.put('ui-grid/selectionRowHeaderButtons',
  '<div ' +
  '  class="ui-grid-selection-row-header-buttons ui-grid-icon-ok" ' +
  '  ng-class="{\'ui-grid-row-selected\': row.isSelected}" ' +
  '  ng-click="grid.appScope.clickConditions() && selectButtonClick(row, $event)"> ' + // Modified template here
  '  &nbsp; ' +
  '</div>'
);

This way, $scope.clickConditions() is evaluated before the actual click logic is called. If it's falsy, then selectButtonClick, which handles the internal selection logic, is never called.

$scope.clickConditions = function() {
  // Check for any other conditions you need
  return !$scope.doingAjaxCall;
};

As I mentioned, this is very hacky! There are better ways to overwrite the templates (e.g. ui-grid/selectionRowHeaderButtons), when overwriting templates you'll have to check the logic when updating, you should probably let the user know that something is happening visually when the AJAX call is performed, etc.

A better solution would be to fork the repo and add your own beforeSelectionChange logic (probably starting here). But it seems like you haven't gotten much help elsewhere, so hope the this gets you started at least!

Anole answered 26/10, 2015 at 15:23 Comment(1)
but the different grids would share $scope.clickConditinions, even though one of them is triggering the ajax call. Sorry but I'm more into looking for the official ui-grid way :( -- there are already some functions (decideRaiseSelectionEvent, etc) but it is not clear in the docs how to use them...Putnem
P
0

ui-grid provides the tools to do this, I'm not sure there's a "ui-grid" way, but there are definitely ways to do it that are compatible.

Based on your description I'm assuming you are only allowing single selection, because if you allowed multiple selection they could keep adding selections and you'd run the ajax in the background. So I assume you're setting multiSelect: false per http://ui-grid.info/docs/#/tutorial/210_selection

I can see two ways to get the result:

  1. If the user tries to select a row whilst an ajax call is running, set the selection back to where it was. This means you'd have to listen to the selectionChanged and selectionChangedBatch events, keep track of the selection that you want, and keep track of when an ajax call was in progress.

  2. Use an isRowSelectable function that doesn't let any row be selected if an ajax call is running. The function itself is similar to what you used to have with ng-grid i.e. return !$scope.doingAjaxCall. The difference is you need to call notifyDataChange whenever you change the value of $scope.doingAjaxCall. From memory making a row not selectable by the user will still allow it to be selected in code - so this won't change that the row is selected.

I'd probably go with the second option.

Adding information as requested: isRowSelectable is in the tutorial as noted above (there's an example of it working). The only trick is that I have a feeling it's only re-evaluated on specific events, so it may not just automatically remove the select from each item when you change the doingAjaxCall variable. Hence I recommended calling notifyDataChange, which is also in the tutorial.

I'd suggest you have a go at it in a plunker, and then if you have difficulty I can look and provide advice. I don't have the time right now to write it from scratch.

Palace answered 18/11, 2015 at 19:16 Comment(4)
Yes, i'm using multiselect: false (will edit the original question right now with that piece of information)Putnem
Can you provide an example code for the second option? i'm not clear if isRowSelectable is part of ui-grid.Putnem
I have added content as requested.Palace
@Palace Regarding this #39271940 I want to limit the selection in my ui-grid to 10. How to achieve that?Ectomy

© 2022 - 2024 — McMap. All rights reserved.