Layout DataTable DOM and CheckBox integration
Layout DataTable DOM and CheckBox integration
I understand from https://datatables.net/reference/option/dom that CheckBoxes (for instance to filter certain data, like in https://datatables.net/forums/discussion/57221/how-do-i-add-checkbox-filtering-to-a-datatable) are not among it's elements.
Issue is that I need to add some checkboxes right between DataTable's length changing input control and filtering input panel but I did not manage to place some custom HTML into the table's DOM section. All examples I've found so far are placing checkboxes above the whole table but layout-wise I can't afford that since I also have a fair amount of columnToggle buttons in a second row.
So what is the best way to place checkboxes among DataTable's elements? Thanks.
My element declaration so far:
"dom":
"<'dt--top-section'<'row'<'col-12 col-sm-6 d-flex justify-content-sm-start justify-content-center'l><'col-12 col-sm-6 d-flex justify-content-sm-end justify-content-center mt-sm-0 mt-3'f>>>" +
"<'dt--top-section'<'row'<'col-sm-12 col-md-12 d-flex justify-content-md-start justify-content-center'B>>>" +
"<'table-responsive'tr>" +
"<'dt--bottom-section d-sm-flex justify-content-sm-between text-center'<'dt--pages-count mb-sm-0 mb-3'i><'dt--pagination'p>>",
buttons: [ {
extend: 'columnsToggle',
columns: [0,1,2,3,4,5,6,7,8,9]
} ],
This question has an accepted answers - jump to answer
Answers
See if this example helps to place the checkboxes within the Datatables
dom
elements.Kevin
That's exactly what I was looking for - thanks!
Seems I have to add the statesave for checkboxes to the
data
forstateSaveCallback
andstateLoadCallback
somehow. Is there an example of how to do it?You would use
stateSaveParams
andstateLoadParams
instead. One option might be to get the checked checkboxes in thestateSaveParams
and save them to an object added to thedata
variable. InstateLoadParams
use that variable to check the appropriate checkboxes.I updated a checkbox search example to show this.
https://live.datatables.net/dayopulu/1/edit
You will need to refactor the code to match your checkboxes. Note it only saves the Position checkboxes not the Office.
Kevin
Thanks a lot, I will try tomorrow and report back.
Weird things: The
stateSaveParams
is working well but instateLoadParams
I am not able to get a hold of my checkboxes. In myI tried other parameters like
input:checkbox[name="region"]
which also work flawlessly forstateSaveParams
but find no elements instateLoadParams
. Maybe the cause is that I integrated my checkboxes in the DataTable UI withbut I don't see why
stateSaveParams
finds them andstateLoadParams
doesn't. MystateSaveParams
works and looks likeIt's possible its a timing issue where
stateLoadParams
runs before thedom
option builds the HTML. Instead of usingstateLoadParams
you might need to usestate.loaded()
in the-event init` event, like the example in the docs.
Kevin
As I understand from https://datatables.net/reference/event/init the
init
event is fired at the same point asinitComplete
, so I put a test to myinitComplete
to see if it's a runtime issue:So the checkboxes are not found after init complete. I have no idea what is going on here Oo
For testing purposes I've put the unchanged checkboxes above the DataTable, out of it's layout, and they are found immediately by
$('input.filter[type="checkbox"]')
and$('input:checkbox[name="region"]')
.So I guess it's safe to say that
stateLoadParams
has some kind of issue finding DT layout integrated elements. Here's the code how I integrated the elements:and outside the DT definition but in the same file:
Try moving this:
Into
initComplete
before the code that loops through the saved checked checkboxes. You might want to remove thechecked
attribute or they will always show checked unless you specifically uncheck them. If you have ajax loaded data there might be.a delay in showing the checkboxes.I think the problem is all the above options are trying to access the checkboxes before the
$('div.toolbar').html(..)
code executes.Kevin
I moved the checkboxes to
initComplete
and they can be found now. But there is the issue now thatinitComplete
is executed right afterstateLoadParams
. If the checkboxes have thechecked
attribute or not -- their init triggersstateSaveParams
and overwrites the last checked states done by the user. So they are all checked or none, depending on their default. Any idea of how to approach this?Assuming you are using
state.loaded()
ininitComplete
to set the checked checkboxes you will want to no do this instateLoadParams
. Maybe you can build a simple test case showing what you are trying so we can help debug.https://datatables.net/manual/tech-notes/10#How-to-provide-a-test-case
Kevin
Here's the test case. I left out the actual filtering done by the checkboxes (which works fine) to keep it simple. The checkboxes are shown at my website but not at LiveTables. I hope this can be fixed somehow: https://live.datatables.net/micudita/1/
You are getting this error in the console.log:
You have a syntax error with the Datatables init code. The test case template uses the non-jQuery initialization. I commented out
columnDefs
because its trying to access columns that don't exist and doesn't affect the test case. I moved thestateLoadParams
code toinitComplete
.I removed the default
checked
attribute from the checkboxes. After loading the state and setting the checkboxes that state needs to be updated to reflect the changes. Otherwise you can get into a situation wherestateSaveParams
will find no checked checkboxes due to the initial state.I created a checkbox change event handler that just calls
draw()
to simulate the search and forces a state save.https://live.datatables.net/tidunube/1/edit
Kevin
Thanks a lot but there's on more issue resulting: Having all checkboxes unchecked is a different use case, because they are meant for optionally reducing(!) data, not enhancing -- therefore they need to be initially all checked.
I have achieved that using the
change
event but it only works for manual click on the checkboxes, meaning the checkboxes are correctly un/checked after page reload but all the data is initially shown as if they were all checked.The cause of this is that
$(this).prop('checked', true/false).trigger('change');
does not trigger thechange
event automatically by page reload and thus all the records are displayed in the DT. I read about.trigger('change')
and this seems to be the most up to day way to go for triggering events from JS. Not working for me though: https://live.datatables.net/tidunube/2/You are getting this error:
The
.trigger('change')
isn't going to have the change events run since those are applied after.You could check the value of
checked from
var checked = api.state.loaded().checked;` to see if its an empty array. If empty then set all the checkboxes as checked. If not then set them all unchecked and let the loop check them.I may have missed it but what exactly happens in your checkbox change event handler? Maybe update the test case to show this. If its using
column().search()
then I wold expect that search to be saved with state save. If using a search plugin then maybe calldraw()
at the end ofinitComplete
.Kevin
Okay, will try that. How are you getting this error, there is nothing shown at my console in Firefox. I'm just using UltraEdit for syntax highlighting, are you using a dev environment for JavaScript you can recommend? Seems I'm missing some useful compiler feedback.
I'm using the Chrome console (not the JS BIN console tab).
Kevin
Okay, based on your help, I got the checkboxes now keeping their state after page reload and the DT is according to their config. But there is one last thing that worked before when I was using
stateSaveCallback
andstateLoadCallback
and is not working anymore withstateSaveParams
andinitComplete
:To be able to use my DT with different datasets and URLs, I overruled the save/load handlers with
localStorage.setItem( '#example' + settings.sInstance, JSON.stringify(data) );
andreturn JSON.parse( localStorage.getItem( '#example' + settings.sInstance ) );
. I tried using them now and can't make it work. I guess the idea still works but where and how to put these lines?Can you update the test case to show the issue?
Kevin
I built a test case with your localStorage statements and it seems to be working:
https://live.datatables.net/tidunube/5/edit
I did find the source of the
Uncaught TypeError: Cannot read properties of null (reading 'checked')
error. If you clear the state then the loaded state isnull
so theapi.state.loaded().checked
fails. Need to add some checks for this. You probably didn't see this error as it would occur only if the state wasn't saved, normally the very first time its run.If this doesn't help then please update the test case to show the issue.
Kevin
Hey thanks a lot for your test case. Since I'm also using Chrome console now I figured the error out yesterday and also could make the
localStorage.setItem
thing work again. I thoughtstateSave/LoadCallback
could not be used in the same DT withstateSave/LoadParam
but I found out it works by accident. But I will look into your test case anyways, especially the code in the.on('change'
function looks way better than mine.Again, thanks loads for your awesome support!!