SlickGrid icon indicating copy to clipboard operation
SlickGrid copied to clipboard

Ability to override getItemMetadata for non-group rows in DataView

Open vlsi opened this issue 6 years ago • 5 comments

DataView always returns null for non-group rows in getItemMetadata: https://github.com/6pac/SlickGrid/blob/14bb1a86a762dd5af1aa280025498353e3b249ec/slick.dataview.js#L455-L471

Use case: "add css class to the grid row when item has certain property". metadata.cssClasses seems to be the way to add row css classes, however DataView does not allow to use that: https://github.com/6pac/SlickGrid/blob/14bb1a86a762dd5af1aa280025498353e3b249ec/slick.grid.js#L1680-L1686

vlsi avatar Jul 20 '18 07:07 vlsi

PS. The sad thing with getItemMetadata is it is used in multiple places, and there's no way to provide the metadata lazily. In other words, metadata.cssClasses and metadata.columns are used in different grid methods, however getItemMetadata has to return all of the metadata values every time.

vlsi avatar Jul 20 '18 07:07 vlsi

Perhaps this lack of row level DataView metadata needs addressing. There have been complaints about how often metadata is fetched, too. I'll be too busy for even minor re-architecting until september. Happy to accept sensible PRs in the meantime.

6pac avatar Jul 22 '18 13:07 6pac

I seem to recall that I added a way to define row css in my personal repo, then added it across to the main repo. I usually document these things by adding an example, rather than by adding to the wiki (bad, I know!). Have you checked out the extended formatter behaviour in http://6pac.github.io/SlickGrid/examples/example2-formatters.html

6pac avatar Jul 22 '18 13:07 6pac

The example linked above seems to demonstrate adding CSS to cells, but not to whole rows.

There are various recipes on stackoverflow for adding CSS to whole rows, as long as you are using DataView. These involve overriding the getItemMetadata method. e.g.

https://stackoverflow.com/questions/8930167/how-do-i-add-a-css-class-to-particular-rows-in-slickgrid

function row_metadata(old_metadata_provider) {
  return function(row) {
    var item = this.getItem(row),
        ret = old_metadata_provider(row);

    if (item && item._dirty) {
      ret = ret || {};
      ret.cssClasses = (ret.cssClasses || '') + ' dirty';
    }

    return ret;
  };
}

dataView.getItemMetadata = row_metadata(dataView.getItemMetadata);

Since I upgraded from v2 to v5, I found I need to provide this context when calling old_metadata_provider:

ret = old_metadata_provider.call(this,row) || {}

Then it works again. I'm unsure whether const item=this.rows[row] or this.getItem(row) (as in the original from slick.dataview.ts) is more appropriate. Both seem to work.

rohanc avatar Oct 17 '23 01:10 rohanc

Since I upgraded from v2 to v5, I found I need to provide this context when calling old_metadata_provider:

ret = old_metadata_provider.call(this,row) || {}

Then it works again. I'm unsure whether const item=this.rows[row] or this.getItem(row) (as in the original from slick.dataview.ts) is more appropriate. Both seem to work.

You need to provide this because we migrated to TypeScript and ES Modules, we no longer use any var which previously had global access scope but since we now use TypeScript Classes, we need to provide the this scope in some cases, I did mention a similar migration step to be done for the DraggableGrouping here but yeah it's possible that there are other special cases like the one you just encountered.

ghiscoding avatar Oct 17 '23 02:10 ghiscoding