Search result highlighting in child rows
Search result highlighting in child rows
Hi there!
I've played with the 2 plugins (Allan's and the Mark.js one) mentioned in the search highlighting blog here: https://datatables.net/blog/2014-10-22
Both work fine, but I wanted to tweak them a little to be able to also highlight text in the child rows. Using the child row example from here: https://datatables.net/examples/api/row_details.html
It's easy to trigger the highlighting when opening/closing the child row by tweaking the click event. But once a child row is opened, how would I keep triggering the highlight code against it? In Allan's code, it is triggered by these events:
'draw.dt.dth column-visibility.dt.dth column-reorder.dt.dth'
When that is triggered, the child rows are not yet part of the table it seems, so their content is not part of the result body. Is there a later event that also includes the child rows, or is there a child row event that can be captured?
Thanks!
This question has an accepted answers - jump to answer
Answers
Will try to get a fiddle example going!
Ok, I've created this fiddle example:
https://jsfiddle.net/7nt58gw3/2/
Search for ABC
It will match only 1 row. Click on the + to view the child row. Notice ABC is highlighted.
Then go back to the filter and continue typing the letter D. The filter should now be ABCD.
The child row still only has ABC highlighted.
How can I refresh the highlighted text in the child row?
Thanks!
A side question that arises from this. The "Draw" event is described as:
Testing confirmed that child rows are not part of that draw, and are done later. Shouldn't child rows be part of the redraw? If not, it would be nice to have an event that has them
Unfortunately there currently isn't an event that is triggered when the child row is shown / hidden (also them changing state doesn't constitute a redraw. I don't know that there is a good and reliable way to got this working simply at the moment.
What would need to be done is the search highligher be modified to work in the child rows and also it add an API method to DataTables which you can call when you show / hide a child row.
Allan
Hi Allan, thanks for the feedback. I looked at the code some more, and I realized that the event to draw the child rows is an extra handler that is added to the draw method.
With the code the way it is now, the event handler to draw the child rows is added AFTER the event handler to run the highlight code. This means that when the highlight code is run, the body does not yet have the child rows inserted. Running it in debug, this is the order of the event handlers in the "draw" for the table:
That last event handler only shows up after I click on a row to have it display its child row. I think I have to get that event to happen before #2.
I think I have a possible solution. Maybe not the most elegant, but here it is. In the datatables.js file, when the event handler to create the child rows is added, I reverse the event handler collection. This might not be the prefered method (possible side effects...will see), but it seems to work. Child rows are now drawn first, and highlight kicks in after, so everything gets highlighted properly.
On line 18024 (after the api.on code), I added this:
var DrawHandlers = jQuery._data(settings.nTable, "events").draw;
DrawHandlers.reverse();
Generally speaking, I think it would be good to have child rows drawn before any other event, unless we do not consider them to be part of the table body? At the moment, we do not seem to be able to control this.
To some extent it isn't part of the table body since it isn't DataTables' core draw method that is inserting the child rows. It used to, but in my (questionable) wisdom I moved all of the child row code into what is effectively an internal plug-in (i.e. a file that could be removed with no effect on the rest of DataTables). The upshot of that is that it only attaches its own
draw
listener when there are child rows to show - which in turn means that it has added its event listener after yours, and since jQuery executes them in sequence...Having the child row draw before the public
draw
event is triggered is a good idea. I've been increasingly thinking about having an internal "almost-done-drawing" event (name tbc...) which would do that. This would be a good reason for me to finally do that - although it would probably be the next major version of DataTables before that happens.In the mean time, a little
setTimeout( ..., 0 );
in your event handler would "fix" it (albeit ugly).Allan
Hey Allan, I appreciate the feedback. I have 2 options for now to deal with this. My reversing the draw handlers also seems to work well; drawback is that I am using a non-standard datatables.js file (that I will minify). I'll flagged this as answered.
I'd like to say a very big THANK YOU for this amazing plug-in. Extremely powerful yet easy to use. Always looking forward to new versions, and it's great to see you consider feedback to make it better.
Thanks again!
Marc