$.extend(true, DataTable.defaults) ignores 'column' defaults in DataTables 3
$.extend(true, DataTable.defaults) ignores 'column' defaults in DataTables 3
K3nguruh
Posts: 9Questions: 1Answers: 0
Hi Allan,
Sorry to bother you again! I'm currently migrating from DataTables 2 to DataTables 3, so I'm noticing a few unusual behaviors along the way. I hope that's okay and I'm not being a nuisance! ;-)
Issue Description
I use DataTable.defaults to define baseline configurations so that all tables share the same default setup. If a specific table requires different settings, I override them directly inside new DataTable().
However, setting global column defaults via column (such as orderSequence) no longer seems to work in DataTables 3, whereas it worked as expected in DataTables 2.3.7.
$.extend(true, DataTable.defaults, {
// layout - works
layout: {
topStart: null,
topEnd: null,
bottomStart: null,
bottomEnd: null,
},
// column - doesn't work (worked in DT 2.3.7)
column: {
orderSequence: ["asc", "desc"],
},
});
const table = new DataTable("#example");
Testcase / Live Example:
https://live.datatables.net/xufodala/4/edit?html,js,output
P.S.: To toggle DataTables 3.0.3 in the live example, please enable/disable the respective stylesheet and script tags in the HTML panel.
Replies
There is not a
columnoption in Datatables so I'm not sure why it worked in DT 2. There maybe undocumented cases from older DT versions that are bugs, etc that worked that are not added to DT 3. You need to use eithercolumnsorcolumnDefsas shown in thecolumns.orderSequenceexamples. I updated your test case withcolumnDefsto show it works:https://live.datatables.net/xufodala/5/edit
Kevin
I have the column's default object aliased to
DataTable.defaults.columnso things likeorderSequencecan have a default set. The property is there, I can see it in the console, but it doesn't appear to be getting used! I'm not sure what has gone wrong there, but I would actually expect that to work, as it did in 2.x I'll get back to you when I've had a chance to dig further.Allan
Hi everyone,
@Kevin thanks for the suggestion, that helped! In my setup, it would need to be
columnDefs: [{ orderSequence: ["asc", "desc"], targets: "_all" }].However, this approach comes with a major downside: you can no longer easily use
columnDefsinside individual table initializations, as the global defaults will overwrite everything—regardless of what you try to set there. Consequently, all subsequent column configurations would have to be handled viacolumns.Testcase / Live Example:
https://live.datatables.net/xufodala/10/edit?html,js,output
So that's definitely a tradeoff to consider. Either way, @Allan mentioned he'll take another look at it.
Okay, I've realised what is happening here. Using
$.extend(truewill copy the array, but it is a deep copy, so since the original default length is 3, and a smaller array is copied to it, the length says at 3 - i.e.copied to:
results is exactly the same as the original!
No that didn't happen in 2.x as the defaults were actually hungarian notation, so
orderSequencewas undefined. I had a mapping in to convert the new style to the old naming. That isn't the case in v3, so we hit this "bug".If you simply do:
Then it will work as expected!
I do have a utility function in DataTables to deep copy objects, but shallow copy arrays, which I thought I was going to be clever with and show you that, but I've just spotted a "todo" note on it for arrays on deep objects. Doh! I'll get that fixed so the utility function is there, but for the moment, just do a direct assignment for any arrays you want to modify on the defaults.
Allan
I've committed the change to resolve that todo item and
DataTable.util.object.assignDeepObjectsis now the function that you would want.Here is the updated test case.
That change will be in 3.0.4
.
Allan
Hi Allan,
Thanks for your efforts!
I wanted to share a custom deep-merge function that I routinely use to combine objects recursively. Perhaps you'll find it useful or interesting as reference material.
The function handles properties as follows:
* Primitive values & Functions: Directly replaced/overwritten
* Arrays: Replaced entirely as a deep copy
* Objects: Merged recursively (retaining existing properties while adding/overwriting new ones)
I created a test case using the
defaultssetup from DataTables. Sincedefaults$3anddefaults$4were referenced as variables in the original source, I resolved them directly within the test object.P.S.: This function could be simplified even further (e.g., using
structuredClone), but native cloning wouldn't be able to preserve function references.Testcase / Live Example:
https://live.datatables.net/rabusexi/1/edit?js,console,output
Very nice - thank you
.
Allan
Hi Allan,
I think I've spotted another issue.
When there are two or more tables on the same page, the previously configured
orderingsettings are not applied to the second table and any subsequent ones. This happens regardless of whetherDataTable.util.object.assignDeepObjectsor$.extendis used.Testcase / Live Example:
https://live.datatables.net/sulilequ/1/edit?js,console,output
P.S.: Do you have a estimated timeline for releasing version 3.0.4 (with the export selectors fix)?
That's a tricky little one! The backwards compatibility actually mutates the defaults object, which is why we see that effect. I've put a little change in to address that, but I might change it further so that defaults does not get mutated, but rather cloned and then modified. I think that would be a better plan in the long term.
Currently expecting to release 3.0.4 next week. Hopefully Tuesday or Wednesday.
Allan