rowCallback breaks sorting
rowCallback breaks sorting
ztgadmin
Posts: 11Questions: 4Answers: 1
Why when rowCallback is used here https://datatables.net/reference/option/rowCallback to update a cell contents the sorting nolonger works. Is there another way to update a cell contents after the rows have been rendered and not break sorting?
This question has an accepted answers - jump to answer
This discussion has been closed.
Answers
Hi,
Thanks for your question. You can't use the
rowCallback
option to modify the data in the DOM and have DataTables use that modified data for the sorting I'm afraid. There are basically two reasons for this:rowCallack
is only called when the row is drawn, but the sorting information might be needed before that (for example whendeferRender
is enabled).The solution to the issue is to not use
rowCallback
to change the data in the cell - rather a data renderer should be used.Perhaps you could give me some more details of what your use case is, and I'll try to fill in the gaps for how to use a renderer to achieve it.
Regards,
Allan
So, part of my issue is that I need to still fetch the data I want to add to the other cells and have not been able to use render to fetch the data then return it.
So, I'm making 2 server calls. Call 1 fetches the first 6 columns of data then adds them to the table using the below code. Then once the data is rendered I tried to make another server call to obtain the data for columns 7 to 27 with the below code
Populate columns 7 to 27
"columnDefs": [
{
'targets': 0
,'render': function (data, type, row) {
//Make server call on once data is returned populate return value
}
}
Populate columns 0 to 6
tblObj.rows.add(JSON.parse(newJSONdata)).order( [[ 0, 'asc' ]] ).draw(false);
I was able to figure out what I needed to do. This ticket can be closed.
Hi,
Great to hear! I'll provide my own thoughts on this if that's okay (without impacting your support credits of course).
You really don't want to make an Ajax call in the
render
function. It is meant to be synchronous and can be called many times.So one option is to use the
createdRow
callback. Then that is triggered, have that make your Ajax call to get the extra data for the row, and then userow().data()
to update the row's data with the new information (this making it available for sorting, filtering, etc).The only disadvantage to that is that it would create an Ajax request for every row. Probably okay for low volume / internal sites, but you would DDoS your own server if it was a busier site!
For that you would need to use
drawCallback
and determine which rows from the existing page don't have the extra data available, then make a single call to get that data.The downside to this approach as a whole is that you can't sort of filter data that hasn't been fetched yet, making things a little more tricky.
How many rows are in your table? Are there enough that including all of the data up front would seriously impact performance?
Allan
Hi Allan,
Sorry for not providing details in what I used. I ended up using the createdRow option then the row().data() API to accomplish my task. Thanks
The number of rows in the table are around 250. The reason I decided to know load all of the data up front was because to obtain the data for the first 7 columns doesn't take much processing time. However, to obtain the data for the rest of the columns can take some time to process. So, instead of waiting for all of the data to load, I wanted to give the perception that the data was loaded faster than it really is by showing the rows and having columns 0 thru 7 populated while the user will see the reaming columns populate with data.