Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cellClass calculated with previous value after cell edit #3449

Closed
admosity opened this issue May 7, 2015 · 13 comments
Closed

cellClass calculated with previous value after cell edit #3449

admosity opened this issue May 7, 2015 · 13 comments
Assignees
Milestone

Comments

@admosity
Copy link

admosity commented May 7, 2015

plunker: http://plnkr.co/edit/rfnc5RctIvFrBZ1jlNJj?p=preview
version: v3.0.0-rc.21

In this example, any cell that gets edited increments the id by 1. Any cell with an even number gets the class injected. The cellClass function is calculated with the old value after the afterCellEdit event is fired. The id increment happens inside the afterCellEdit.

My use case for this is I want to implement a column that shows if the row has been edited or not and whether it passes validation:

This is what happens after the first edit:
image

If I make another edit, or edit/cancel on the same row, it processes correct:
image

When I change it to a valid email:
image

And when I double click and cancel (yellow for modified and valid):
image

@squarewave24
Copy link

trying to solve a similar problem. did you ever figure it out ?

@admosity
Copy link
Author

I did a workaround somewhat...

I had a class injector that is fed a mapping of classes and a model to watch. It watches for changes in the model and pulls the appropriate class out to inject and toggles off the old one.

  module.directive('classInjector', [

    function() {
      return {
        scope: {
          watchModel: '=',
          classMap: '=',
        },
        link: function(scope, elem, attrs) {
          var lastClass;



          var watcher = scope.$watch('watchModel', function(newValue) {
            if(newValue != null) {
              if(lastClass) {
                elem.removeClass(lastClass);
              }
              lastClass = scope.classMap[scope.watchModel];
              elem.toggleClass(lastClass);
            }
          });

          scope.$on('$destroy', function() {
            watcher()
          });
        }
      }
    }
  ])

My column def for that column was

          {
            name: '_modified',
            displayName: 'M',
            enableCellEdit: false,
            cellTemplate: '<div class="ui-grid-cell-contents modified-indicator"><i class-injector watch-model="COL_FIELD" class-map="grid.appScope.classMapping" class="fa fa-circle"/></div>',
            width: 100,
            filter: {
              type: uiGridConstants.filter.SELECT,
              selectOptions: [
                { value: 0, label: 'Invalid' },
                { value: 1, label: 'Valid Unsaved' },
                { value: 2, label: 'Saved' },
              ]
            }
          },

My class mapping for reference:

      $scope.classMapping = {
        0: 'modified-invalid',
        1: 'modified-valid',
        2: '',
      };

Notice the classInjector directive on the i element. I'm not sure how performant this would be when there's much more data, but it seems to work pretty fine for me at the moment...

Hope this helps!

@squarewave24
Copy link

thanks! this is crazy though.. all im trying to do is show dirty rows after cell edit :)

do you know why something like gridApi.core.refresh() is not working? I'd imagine that I could call that to trigger the cellClass function ..

@admosity
Copy link
Author

I remember trying variations of that and even dropping in random digest calls everywhere... Nothing worked so this is what I came up with.

@squarewave24
Copy link

this is wild! such a simple thing.. spending hours in getting it to work :/

have you tried other events ?
http://ui-grid.info/docs/#/api/ui.grid.rowEdit.service:uiGridRowEditService

@PaulL1
Copy link
Contributor

PaulL1 commented May 15, 2015

The cellClass isn't a watch/bind, because if we did that we'd end up with an extra watcher for each and every cell - and watchers go directly to our performance (watchers fire on every scroll tick).

In general cellClasses don't need to be recalculated unless the data changes. Data doesn't change very often. Whenever data is changed, we call notifyDataChange, which should update the classes. We call this from the after edit.

Most likely thing here is that you're making a change in the afterCellEdit, and that perhaps fires after the notifyDataChange.

@squarewave24: the rowEdit feature already shows dirty rows does it not? Can you leverage that?

@admosity: this plunker uses notifyDataChange to address your issue I think: http://plnkr.co/edit/ao5XEEfhnxyfxcjFbzBA?p=preview

@squarewave24
Copy link

have you tried this approach?
#2070

looks promising but still getting an error, but think this is close:

if (newValue != oldValue) {

    rowEntity.dirty = true;
    gridApi.core.notifyDataChange(gridApi.grid, uiGridConstants.dataChange.EDIT);
}

@squarewave24
Copy link

i have not tried rowEdit feature, researching it now thanks!

@squarewave24
Copy link

@PaulL1 do you know why ridApi.core.notifyDataChange can throw this error?

Notified of a data change, but the type was not recognised, so no action taken, type was: [object Object]

@squarewave24
Copy link

hey @PaulL1 thanks that plunkr had an example that worked for me!

gridApi.core.notifyDataChange(uiGridConstants.dataChange.COLUMN);

it's really hard to find any documentation on all of these services.. seems like forum post examples is the only place :/

thanks for responding so fast.

@admosity
Copy link
Author

Welp, could've used that sooner. Thanks!

@PaulL1
Copy link
Contributor

PaulL1 commented May 15, 2015

Yeah, notifyDataChange is a bit complex unfortunately. There is some info in http://ui-grid.info/docs/#/api/ui.grid.core.api:PublicApi, and more info in http://ui-grid.info/docs/#/tutorial/316_dynamic_data_changes

@PaulL1 PaulL1 self-assigned this May 15, 2015
@PaulL1 PaulL1 added this to the Future milestone May 15, 2015
@PaulL1
Copy link
Contributor

PaulL1 commented May 27, 2015

Tying to #3603, which will change the architecture to be a bit more easily understandable.

@PaulL1 PaulL1 closed this as completed May 27, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants