Problem presumably related to row().invalidate()
Problem presumably related to row().invalidate()
Hi everyone .
I have the following use case:
My data is from multiple tables that are being joined. Most of it is 1:1 relation, but some is 1:n.
Now I want to omit the duplicate data from my Datatable, at least when it's appropriately sorted, and I'm facing some side effects.
Here's an example for what I want to do:
https://live.datatables.net/julaqeba/3/edit
The relevant stuff is in the rowCallback function.
What my example does is:
- checking if two lines following each other have an identical Position text
- if so, omit the Position text from all rows following the first one
This works, but I have to invalidate all rows, otherwise, when I re-sort the table, bad things happen.
Now, I have an unexpected side effect: with default ordering, you'll notice that the Salary column in the first row is right aligned while it is left aligned in all following rows.
Somehow, my row invalidation efforts are removing the dt-type-numeric class from all but the first row (in my actual application, it removes the date class etc.).
Can somebody shed some light as to why that happens or maybe I'm overcomplicating things in my approach?
Thanks bunch in advance!
This question has an accepted answers - jump to answer
Answers
You are invalidating the entire row. Have you tried invalidating just the position column? That would be something like this:
Assuming that position is column 3
Well, in my actual project I'm omitting text for like half the entire row. So this would probably just shift the side effect around, I guess. I feel that there must be a better approach to this problem, which I seem to be unable to find Thanks anyways!
Not sure I understand all of what you are trying to do. Maybe the RowGroup extension will do what you want.
Kevin
The RowGroup extension looks very nice (saw it before), but it doesn't exactly do what I want. Since most of my table data is 1:1, it would add many additional rows that aren't needed, since there is only 1 element in the group.
Maybe I could try getting it to work so that it only creates a group when there is more than 1 element in it, but I didn't see any examples for that, so I'm not sure if it's possible.
I'll try to explain better what my original idea is: most of my data looks like this:
But then I also have:
When there are identical order numbers following each other, I just want to display the order number in the first row and omit it in the following rows (this is a simplified example, actually I want to "hide" the content of like half the columns of my table).
Thanks again.
I see, I wasn't able to run the test case earlier on my phone
Removing
row().invalidate()
doesn't seem to affect sorting in the test case.https://live.datatables.net/julaqeba/8/edit
I'm not sure its doing anything useful for you nor do I think you want to use it as I believe
i.innerHTML = "";
is intended as a temporary display of an empty cell. Meaning you don't want to change the original data.Can you provide steps to replicate the sorting issue?
Kevin
Thanks for your time . Not calling "invalidate" makes the table go haywire (well, calling it does too, I'll get to that in a few seconds). It's a bit tricky to reproduce here, but this are the steps:
1) sort by Name column, ascending
2) verify that "Abbey Jobson" has "Machine Operator" as position
3) filter the Position column for "Machine Operator"
4) sort by Name, descending this time
5) jump to the last page (should be page 7)
6) "Abbey Jobson" doesn't have "Machine Operator" next to it
7) sort by Name column, ascending, and remove search filter
8) "Abbey Jobson" still doesn't have Position
So, something is amiss there.
"invalidate" makes things even worse, as I just noticed. When I uncomment
again, on every keypress in a search box (even backspace) there are entries disappearing from the table (10 entries at a time, so an entire page). This seems to happen if the table is sorted by the Position column.
So this is certainly not the solution either. I didn't notice this in my actual project, but will re-check tomorrow.
I just tried the suggestion rf1234 made earlier and invalidated only the cells that I actually change. But that doesn't work either:
https://live.datatables.net/yaxubuli/1/edit
This also makes rows randomly disappearing or missing content.
Thanks for the detailed steps, it helps! Looks like you need to reset the first row on the page, for example:
https://live.datatables.net/julaqeba/9/edit
With this each page displays the position in the top row. Not sure if that's what you want but maybe it will get you closer.
I don't think you will want to use any of the invalidate APIs for this requirement.
Kevin
Thanks Kevin, however, your approach still has problems with cells staying blank after re-sorting. Also, it doesn't restore the rendering and class information.
I did it like this now:
https://live.datatables.net/kizapusa/1/edit
This looks very messy again, but it seems like it's working.
I'm basically manually storing the HTML and Class data before I remove it, and restore it when required.
Maybe someone has an idea for a cleaner approach that doesn't require storing this "by hand"?
Cheers and thanks for your help again
Are you using
storage_html
to store the cell data because you are usingcolumns.render
to display the data? Instead you can usecell().render()
to get the displayed cell data. This will save using one data structure.I updated my last example to use
columns.render
for the position column andcell().render()
to grab the displayed cell data.https://live.datatables.net/nehiwabe/1/edit
Also note you can get an instance of the DT API by using
this.api()
. I updated my last example to show this but forgot to point it out. For example:I didn't understand the use of
i.classList.remove("dt-control")
. Just thought it was an example and I didn't include it in my example because it didn't make sense to add that class to the position column. Are you trying to workaround the issue that you aren't usingcolumns.className
to assigndt-control
to the first column?And are you only trying to add and remove the
dt-control
class to the first column based on whether the cell is blank or is showing the cell data?Assuming that is what you want I added this code:
And only remove the class is the position cell is set to display an empty string.
Kevin
I should add that the test case also uses
column().header()
andcell().node()
.Kevin
Thanks a bunch, I'll probably look into this next week . There's a bank holiday here tomorrow, and I took Friday off.
Cheers!
Hey Kevin. I finally got around to testing your solution. Everything worked out fine, except that there was an "else" branch missing for the
if (prev_data == cur_data)
condition (with the same content as the "else" branch forif (displayNum > 0)
). Still, now the code doesn't as convoluted as it did before, so thanks a lot again for your time.I'm not sure what the else would be for but glad you got it working.
Kevin
The
else
is required so that the error from a few posts earlier (the 8 steps I supplied to reproduce it) does not occur, it still happens in your example . Cheers.Hmm, I followed those steps and it seems to be working correctly. Here is a screenshot after step 8 with Abbey Johnson having the position of
Machine Operator render
:I guess it doesn't matter if you have it working the way you want. Maybe what you want is different than what I interpreted. If you want to show us please update the test case to show the needed change as I don't know what is in the else clause you added.
Kevin
7) sort by Name column, ascending, and remove search filter
This step was unclear, you first have to remove the search filter and then sort by Name column. But no need to further improve your example, since I have it working. The additional
else
branch contains the same code as theelse
branch forif (displayNum > 0)
.Cheers.
Cool, thanks for clarifying. I see the problem now. Here is the updated test case in case anyone else is interested:
https://live.datatables.net/nehiwabe/3/edit
Kevin