angular-ui / ui-grid

UI Grid: an Angular Data Grid
http://ui-grid.info
MIT License
5.39k stars 2.47k forks source link

UI Grid Validator and afterCellEdit function calls #5577

Open parag-patil opened 8 years ago

parag-patil commented 8 years ago

Hi,

I am using UI grid with validator module. I have below field with validator. I have written custom datatype validator.

{field: 'Qty', displayName: 'Qty', width: '10%', validators: { required: true, datatype: 'int' }, cellTemplate: 'ui-grid/cellTitleValidator'}.

My validator is being called correctly once I edit the cell but in below function, rowEntity is not being updated correctly for rowEntity['$$errors' + colDef.name]. Seems till the time below function is called, validator moudle has not added ($$error) property for rowEntity. My requirement is, if rowEntity do not have property with $$error+.... then save record otherwise do nothing. Is there way to run below function only after validator has updated the rowEntity?

//After cell Edit is completed. $scope.Grid.onRegisterApi = function (gridApi) { $scope.gridApi = gridApi; gridApi.edit.on.afterCellEdit($scope, function (rowEntity, colDef, newValue, oldValue) { }); };

parag-patil commented 8 years ago

Has no one experienced this problem? Before validator set the $$error property for colDef, my gridApi.edit.on.afterCellEdit() is getting called and there is no way to find if edited value is correct or not as $$error is not updated when call comes to gridApi.edit.on.afterCellEdit() . Not sure how I can force ui grid to call gridApi.edit.on.afterCellEdit() this only after completing validators call.

parag-patil commented 8 years ago

@imbalind Can you please guide here.

Charlie-Ng commented 8 years ago

+1 I think I am running into this issue too. I am checking the boolean value of gridApi.validate.isInvalid(row, col) inside afterCellEdit, but it always returns undefined the first time.

Charlie-Ng commented 8 years ago

I looked into the code and found that rowEntity does not have $$invalid+whateverColName property immediately. It does on the second or third isInvalid call.


      isInvalid: function (rowEntity, colDef) {
        return rowEntity['$$invalid'+colDef.name];
      }, 

Guessing it is related to a timing issue. I kind of got it to work by using a $timeout.

 vm.gridOptions.onRegisterApi = function(gridApi) {
                $scope.gridApi = gridApi;
                gridApi.edit.on.afterCellEdit($scope,
                    function (rowEntity, colDef, newValue, oldValue) {

                        $timeout(function() {
                            if (!$scope.gridApi.validate.isInvalid(rowEntity, colDef)) {  
                                //do something
                            };
                        }, 0);

                    });
}

Please help! thank you.

parag-patil commented 8 years ago

Hi charlie, Even I am also waiting for proper solution on it. But for time being, I am checking for $$error and $$invalid in saveRow method instead of edit, But it has some delay. Seems code statements in edit are getting executed asynchronously before ui grid adds $$error and $$invalid.

paulcolucci commented 8 years ago

I am experiencing the same issue.

In gridApi.edit.on.afterCellEdit the code: rowEntity['$$invalid'+colDef.name] only returns the correct errors every other time I edit. It would be great to get this consistent so that I can check for errors in the afterCellEdit function.

imbalind commented 8 years ago

Sorry for the late reply, but I'm not working on this anymore and I'm currently out of the loop.

Anyway, the problem here is that validation was not originally meant to work with async validation. It was added later.

This led me to use only 2 states: valid, invalid.

There's no way for a grid driven validation to be intercepted, hence there's no way to be sure that validation has ended.

I see two possible solutions here:

  1. Edit the source to add a third state: pending validation.
  2. Launch runValidators a second time and wait for the returned promise (thanks to @imranamans for the useful addition) to fulfill.

The first one is cleaner, but you need to make sure that anything will continue to work for other users before submitting a pull request.

The second one is a bit dirty, because you basically execute your validator twice, but it could be acceptable in certain situations.