Keep child rows open after ajax reload
Keep child rows open after ajax reload
When I do an ajax reload on the parent table, I would like to keep all childs open.
There are quite a few posts on this topic both in the forums here and on stack overflow. None of which I was able to get working.
One post seemed to indicate the API at some point started to support this.
https://datatables.net/forums/discussion/61778/keep-child-rows-open-on-draw
I have tied to turn on responsive to enable this feature but when I do so, the layout changes in a weird way.
With "responsive": false,
the carrot is on the right side of the table and the child table opens just fine
With "responsive": true,
the carrot shifts to the left side of the table and the child table does not open.
Here is a screenshot with the child table open with `"responsive": true,
Answers
The first problem is you can't have both Child Detail Rows (which I believe you have assigned the last column) and Responsive child rows. See the compatibility matrix. You will need to use a modal display for Responsive like this example.
The thread you linked to is specific to Responsive child rows and using the row id.
Here is an example using
ajax.reload()
with the callback function to loop through the collected open rows to reopen Child Detail Rows. This blindly does the work without making sure its reopening the correct row. Test to make sure it works for your solution. You may need to userows().ids()
to make sure to reopen the appropriate rows.https://live.datatables.net/niwimexu/1/edit
Kevin
Thank you for this sample. Ill pick up this project again in the morning.
Kevin,
I couldn't get your example to work either. I am missing something obvious that should be staring me in the face.
When the main table refreshes, all the childs close and they do not reopen.
I put my code on datatables live, its an editor solution so I don't think it will run on datatables.live but at least you can see what I am doing and perhaps spot what I am doing wrong.
https://live.datatables.net/yalasixo/1/edit
You can use the JS Bin
Add library
menu option to add Editor and the other extensions. For example:https://live.datatables.net/yalasixo/2/edit
However the test case is using an ajax url that is not accessible.
I guess this is the code you are having difficulties with?
I would first do some debugging to see if
noteChildRows = mainTable.rows('tr.shown');
is finding the shown child rows.Next I would debug this loop:
Make sure
d = this.data();
is the correct row. Not sure this is correct:I think you will want to remove the
this.
part as you are just calling a function.Kevin
I didn't know there was a shortcut to add in js. into datatables.live That is certainly helpful.
data tables live is responding with an console message "error on line 0". Not sure what that means, but I see the JSON strings are not loading.
noteChildRows = mainTable.rows('tr.shown');
This gets the row number. such as 0 1 2 3 but the row numbers are really row_860 row_861 row_862
I wonder if this is not the issue. Or at least the first issue. All the examples out there that show how to do this dont harvest row numbers in the format row_861 but instead harvest 0 1 2 3
The message I get in browser console is
row data is not a fuction
This error doesn't make a whole lot of sense. It was obviously a function when the child was originally created, why its not a function now is a very odd.
I figured out my issue in part.
All the examples use a subroutine named "format" where the html that creates the child table is expressly typed. I let datatables make the table html so I thought I didnt need this fuction. Turns out I do... I dont want to expressly type the html that datatables does automatically.
How can I turn this into the automatic datatables version?
I noticed another issue:
You have
d()
in thecreateNoteChild(rowIdx, d())
function call. Remove the parentheses as this is not a function but a Javascript variable.Datatables doesn't make the table HTML. You need to create this. You don't have to use the
format()
function. You are doing the same as the format function with thetable
variable in this code:Kevin
Hi Kevin,
Here is my updated code
I am now getting two errors.
Error #1 - createNoteChild is not a function
Error #2 - nodes is not a function
As I mentioned before:
I think this is due to a change in Datatables 2.0. 1.0 allowed for
row().nodes()
(plural nodes) to work even though there is no API for this. The loop is one row at a time sothis
is equivalent toapi row()
. Use this instead:Kevin
Hi Kevin,
Here is the latest update of code
And here is the most recent error;
Ive retooled and gone back to this example;
https://datatables.net/blog/2019/parent-child-editing-in-child-rows
Scroll down to the bottom and look at "Updating the parent table"
This is exactly what I am trying to do... but it also does not work.
The child closes on reload.
Here is my code;
Sorry I believe this should look like this:
The
cell()
API takes the following parameters in order,row
,cell
. You are referring to the first cell in the row with0
. I think you said the child row click element is in the last column. Change the index to match.The example I gave reopens all open child rows on
ajax.reload()
. The solution provided in the blog only reopens the row that was edited. Maybe this is all you want.Kevin
Very nice. We are now updating the class. Now to get the actual opening of the child table working.
Here is my latest code.
for
this.child( $(format( d ) )).show();
i dont need to trigger the function named formatso I think that all I need to reopen a child is
$(this.node()).show();
so I change my code as follows.but it doesn't work the child stays closed after the reload.
This is using jQuery show() which won't work.
Maybe
row().child.show()
will work. Something like this:Kevin
no luck. the child stays closed.
here is my latest code
Have you tried using
createNoteChild(rowIdx, d);
in place ofthis.child.show();
?Possibly you can adapt the
click()
method used in the blog:Replace the
0
index with the column index you have the chid row details button in.Kevin
I feel like we are getting in the weeds here and need to backup and establish a baseline.
Going back to this example as a baseline;
https://live.datatables.net/niwimexu/1/edit
Lets use a button click to retrigger the action of reloading the parent table and reopening the child table.
The result, an incorrect version of the child table loads.
Here is the code;
https://live.datatables.net/yalasixo/3/edit
disclaimer: one of the java script includes is throwing an error so the above example does not work but all the code is there and it does indeed work in Visual Studio. Everything is the same except in Visual Studio the JSON string originates from a database, in the live.datatable example the JSON string is a fixed string.
Step #1 - Open a child table
Step #2 - Click on reload table
Step #3 - Notice the wrong child table loads
Obviously the wrong child table loads, its pulling from the format function. How can I reload the original child table that we see in Step #1 ?
-David
You are getting this error:
Click on the Errors area at the bottom of the Javascript tab. You have this:
I commented out the ajax option.
Now this error:
This won't work:
if you want to add Javascript data then use
data
notajax
. See this example. Also remove theserverSide
option since you aren't using theajax
. Or use one of the SSP JS Bin templates.When you click the row to open the child you use this code:
Instead of using the format function:
Why not call the
createNoteChild
function:Kevin
regarding the live.datatables
Im trying to get a working example that we can both use, there are errors, but I cannot see the difference between erros and warnings and I believe I am missing at least one warning or error that is not displayed on the list.
Here is a link to a video on dropbox to show you what I am seeing;
https://dropbox.com/scl/fi/ev36mmkziinm41zbml26w/ErrorsAndWarnings.mp4?rlkey=yxo4d0kzjcr9dff314zsxja49&dl=0
regarding why I dont use the createNoteChild funciton, I get this error message when I call it. Which is very perplexing as I dont get that error when the function is called the first time around.
How are you calling createNoteChild?
My suggestion is this:
this
in therows().every()
loop is therow
API for the row. Should match how you are using therow
parameter in the function.this.data()
is therow().data()
for the row. At least thats how I beleive it to be. You can put a debugger break point oncreateNoteChild(( this, this.data() );
to see what the two values actually are.Kevin
I am exactly calling based on your suggestion that throws the error
row.Child
is not a function.Here is the call I am using;
I had a bit of time to build a test case utilizing much of your code. Did not include Editor but created two buttons' One to call
createNoteChild()
and the other to use the click method found in the blog.https://live.datatables.net/yaroyala/41/edit
Both options seem to work.
I building the test case I noticed an extra
(
in my suggested code snippet. Looks like you added an extra)
which is causing(this, this.data())
to be passed into thecreateNoteChild()
'srow
parameter. Nothing is passed to thedata
parameter. It should look like this:Kevin
Well its always something simple isn't it? Golly.
The next couple of weeks I am working on other projects. Ill circle back around to this in approximately two weeks.
Thanks for the assistance Kevin. I appreciate it!
So with Kevin's most recent suggestion, the reload of the child table still didn't work. Although Kevin;s most recent suggestion did help to correct a typing error that was causing issues. There was still something aims.
I then thought to myself... what if the attempt to reopen the child table is just triggering to soon? So I put a 2 second delay on the child reopen loop, and it worked!!!!
Here is my code showing the 2 second delay.
This is the hook I am using to trigger the child table reload, on editor submit. It was just triggering way to soon.
I then move the trigger to the child editor's AJAX "success" response, removed my 2 second delay, and PRESTO! It worked!
That seems strange. You might need to wait on the DOM to be updated but 2 seconds seems a lot. Have you tried a smaller number like 100 or 200?
Kevin
I didn't test for a shorter time, I just immediately moved the trigger to JSON:Success with no delay and it worked
Are you saying you added the
success
function to theajax
option? Doing so is not supported. This is from theajax
docs:Maybe use the
xhr
event instead.Kevin