ashl1 / datatables-rowsgroup

The Datatables feature plugin that groups rows (merge cells vertically) in according to specified columns.
Other
95 stars 94 forks source link

No Grouping when using render option on columnDefs option #14

Open acjackson opened 7 years ago

acjackson commented 7 years ago

Hi,

I'm using an ajax data source and use the columnDefs.render Option to manipulate the data. But there is no grouping on the specified column. If I do NOT use the render option and use the columns option instead (not applicable on my project) it works as expected.

live example http://live.datatables.net/logubedu/1/edit

ashl1 commented 7 years ago

Hmmmm... The problem is much more deeper than I supposed.

First of all, I can simply fix your case in example. I can change to deep compare objects from "data" array. But his only helps in the case. To provide more universal solution (which works for any render() function, also if it depend on row), more investingating required. Or I can ask for comparators - the functions that compare data for specified columns in your way. This provide more universal solution (because you don't depend on 'display' type and can use any comparison). To make the example work we need to make a function for render, set up it for Rowsgroup and in columnDefs like this:

columnDefs: [
  {
    render: renderFunc,
    targets: '_all'
  }
]
comparators: [
  (a, b) -> render(a) === render(b)
]

renderFunc () {
  ...
  return value;
}

What do you think? Will the solution with comparators satisfied you?

To not forget:

  1. column().data() only returns raw data values. But updated after ordering and so on
    _api_registerPlural( 'columns().data()', 'column().data()', function () {
        return this.iterator( 'column-rows', __columnData, 1 );
    } );
  2. cell().render('display') return the result data will be shown in table. But will be! It seems the new data (applied immediately after calling order()) isn't change until actual render()
    _api_registerPlural( 'cells().render()', 'cell().render()', function ( type ) {
        return this.iterator( 'cell', function ( settings, row, column ) {
            return _fnGetCellData( settings, row, column, type );
        }, 1 );
    } );

    I'm not sure it works in another plugin

acjackson commented 7 years ago

First of all, I can simply fix your case in example. I can change to deep compare objects from "data" array. But his only helps in the case.

Could you post a fixed version for me to test?

Or I can ask for comparators - the functions that compare data for specified columns in your way. This provide more universal solution (because you don't depend on 'display' type and can use any comparison).

So I reuse my existing render function for comparison? And this comparison would only be executed on the columns I specified in the rowsGroup option?

 rowsGroup: [
        0,
 ],

What do you think? Will the solution with comparators satisfied you?

Sounds fine to me :smiley_cat:

acjackson commented 7 years ago

As a quick fix, I use this deepEqual function from https://stackoverflow.com/questions/201183/how-to-determine-equality-for-two-javascript-objects

function deepEqual(x, y) {
  const ok = Object.keys, tx = typeof x, ty = typeof y;
  return x && y && tx === 'object' && tx === ty ? (
    ok(x).length === ok(y).length &&
      ok(x).every(key => deepEqual(x[key], y[key]))
  ) : (x === y);
}

and replaced this line

if (columnValues[iRow] === columnValues[newSequenceRow]) {

with

if (deepEqual(columnValues[iRow], columnValues[newSequenceRow])) {
ashl1 commented 7 years ago

Yes. I mean exactly you wrote about quick fix. But this is not universal. What I mean is the setting like:

rowsGroup: {
 groups: [ 0 ],
 comparators: [(a, b) -> renderFunc(a) === renderFunc(b)]
}

where renderFunc is the function of your render. Because it's universal you can simply change it to whatever you want. For example:

rowsGroup: {
 groups: [ 0 ],
 comparators: [deepEqual]
}

It's decided. I will do just that at my next free weekand.

vince844 commented 1 year ago

Hi, i've got the same problem. Any fix yet?