datatables-rowsgroup icon indicating copy to clipboard operation
datatables-rowsgroup copied to clipboard

No Grouping when using render option on columnDefs option

Open acjackson opened this issue 7 years ago • 5 comments

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

acjackson avatar Aug 25 '17 14:08 acjackson

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 );
	} );
  1. 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

ashl1 avatar Aug 26 '17 17:08 ashl1

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 avatar Aug 29 '17 11:08 acjackson

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])) {

acjackson avatar Sep 04 '17 09:09 acjackson

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.

ashl1 avatar Sep 04 '17 09:09 ashl1

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

vince844 avatar Dec 18 '22 09:12 vince844