Possible bug in ColVis button
Possible bug in ColVis button
Just curious if anyone else has reported this. It's not huge for me as I can keep using the older version, but it's always nice to ensure all libs are on their latest versions to ensure compatibility.
When I use 1.7.1 for DT buttons, everything works just fine when I change columns (show/hide) and refresh/reload my table. However, when I use version 2.2.2, it breaks this functionality.
I receive the following error message: TypeError: undefined is not an object (evaluating 'c.offset().top)
I'm be putting together a test case to try and reproduce the issue I am seeing. But my guess is, with the latest version, there's something my code isn't handling. For example, I had to update my refresh code to destroy the button container as the latest version was making a copy of the buttons whereas it didn't do this before.
This question has accepted answers - jump to:
Answers
We're not aware of anything that would break between those versions. Both your issues, the error message and the need to destroy, we wouldn't have expected.
I've knocked out this test case with a single button - could you describe how we could see those two issues using that, please?
Thanks,
Colin
@Colin I made a copy of what you have and modified as best as I could towards my example: http://live.datatables.net/sikufuvi/1/edit?html,css,js,output
`$(document).ready( function () {
var table = $('#example').DataTable({
dom: 'Bfrtip',
buttons: [
"colvis",
{
"text": 'Refresh',
"action": function (e, dt, node, config) {
if ($.fn.dataTable.isDataTable("#")) {
// Show a spinner in case this process takes a long time.
this.processing(true);
});
} );`
I'm seeing this error when clicking the Refresh button:
I changed this:
to this:
And now the Refresh button seems to work. At least its not generating any errors
http://live.datatables.net/gahujefu/1/edit
Can you provide the steps needed to see this error?
Kevin
Basically, I have a row of buttons in my app that includes ColVis and a custom refresh button. The table's data is drawn from Jira via Atlassian's REST API.
With ColVis on v1.7.1, I can change the visible columns and hit my refresh button and it redraws everything as expected. This is done in case new data was added to Jira while looking at the table in my app. Instead of hitting the browser refresh, I added it directly on the tables.
With ColVis 2.2.2, when I change the columns and hit my refresh button I get the error I described above. With 2.2.2, I fixed the copying of the buttons using destroy(). I did not have to do this before.
So, with updating to the newer libs I am sure I am missing something to ensure it works or I may need to recode something that I did incorrectly that wasn't being caught before.
Either way, I "never" blame DT because it has been ROCK SOLID for me since I started using it in 2020. All errors have always been on my end.
@kthorngren sorry that was a typo on my part. I tried to walkthrough the steps above for my specific case. My biggest issue is, I can "never" reproduce my issue outside of my app. LOL.
Basically, when the table is created, I am fetching data via an API for Jira. From there, I build the table and all is well. With 1.7.1, The refresh code (listed above), simply emptied the table, turned off any selections, etc. and then recalled the setup function which goes out, grabs the data again in case there were any updates, and redraws the table.
If I point to ColVis 1.7.1, this all works perfectly. When I point to 2.2.2, that's when I get the error. Maybe, I'm not fully destroying everything--just need to find out what it is.
Hmm, not sure. Looks like you have removed code for redrawing the table. Please post all the code for that function.
What click event are you trying to remove?
I suggest moving this as the last thing you do after removing any Datatables specific items such as using
destroy()
.Kevin
Sounds like you might be rebuilding the
table
from scratch in your function to fetch from the API. Maybe you just want some thing like this:http://live.datatables.net/sanuvoso/1/edit
First it uses
destroy()
then empties the table with$("#example").empty();
.Kevin
@kthorngren unfortunately, the redrawing code is lengthy because it involves accessing another API. I'll add that as a last resort as I think in the refresh I am not taking care of something. If the table draws initially AND I can hit my refresh button and redraw with no issues, I don't think that code matters. It's only when I change the columns and refresh that something is going wrong. So, I'm focusing there and will dig deeper.
One thing I noticed in the console is I'm using jquery-3.6.0. Most examples seems to be using query-3.5.1. So I will go back to 3.5.1 and see if that helps. Could be I'm using incompatible versions.
Oh and to answer your question, I have a checkbox row that allows users to select the rows. I also have the checkbox in the header row for a "select all" and use a button to "select all current page". As I am redrawing the table, I am cleaning up any selected or showing of the detail rows.
Updated note: I'm trying to upload screenshots so you have a visual but it is not allowing to do so.
jQuery version shouldn't matter.
Are you reinitializing Datatables in this function or just rebuilding the HTML table. Understanding this process might help. If you are hiding a column then just simply rewriting the HTML table then I can see an error being generated.
Kevin
@kthorngren ok, I had my my destroy after my empty, but using this example: https://datatables.net/reference/api/destroy()
I put my destroy before my empty and that seems to work--although it gets rid of my headers and the click functionality, but that's another issue. LOL.
As always, thanks for the assist!
destroy()
will remove any event handlers it has bound but if you created others they won't be removed. It supposed to leave the HTML table in its original state. The$("#example").empty();
will remove the HTML table, headers and all.Kevin
How are you loading the table data from the API?
Kevin
@kthorngren ok so I have to figure out what's going on with my app when I try to use fixedHeader or a scrollX/scrollY window.
I reset my app back to it's original state and turned on the latest libs (including ColVis 2.2.2) and it works perfectly.
The app has been in the wild since 2020 and no one has complained about not having a fixed header, so I'll take my time and go through the code more thoroughly. But for now (and tomorrow's demo), I should be fine with what I have since it is more of an incremental update versus adding new functionality and trying to make it sexier.
The only issue I'm having with fixedHeader: true is that it seems to lose the table's column settings. I had another thread where I got this working, but the solution seems to break something else. Lol.
But again, if I don't set column widths at all, I get funky column widths, but fixedHeader: true works just fine. So I need to dig and figure out where I am losing the column widths. It may be like you stated where I need to use destroy() instead of empty().
No worries, if I figure it all out, I'll be sure to post the solution. Thanks for the help!
Quick update. So it seems my issue is that the initial fixedHeader is being stored and when I refresh the table, I am not updating it or destroying it properly. I've searched the forums and have only found custom methods for destroying the fixed header but those solutions do not resolve my issue. I also tried to use fixedHeader.disable(), columns.adjust(), and fixedHeader.adjust(), but none have resolved the issue.
Goal: Start using fixedHeader for clients that produce thousands of rows in the tables.
Test cases:
* fixedHeader false: Redraws just fine with and without column toggling (show/hide).
* fixedHeader true, no column toggles: Successfully redraws.
* fixedHeader true, column toggling: Fails to redraw
Pseudo code to explain posted code.
1. First thing I do is sow the spinner for progress.
2. Next I remove the classes for selected rows, note that special is nothing special so don't worry about that at all.
3. Then I remove the click event so if the user selected something before refreshing the table it simply ensure nothing is selected once the table has been redrawn.
4. Next I have a tracker to determine if this is the first time the table is being drawn or a refresh.
5. Then I empty the table.
6. And finally, I call the method that re-grabs the data and redraws the table.
` {
// Setup the button code and action.
"text": '<i class="fa fa-refresh"></i>',
"titleAttr": 'Refresh the table',
"className": 'rw-button',
"action": function ( e, dt, node, config ) {
if ($.fn.dataTable.isDataTable("#projects")) {
// Show a spinner in case this process takes a long time.
this.processing(true);
Ok guys, please don't hurt me on this one.
What I discovered is I had an old jquery line that was conflicting with the DT jquery reference. I also had to change my $("#projects").empty(); to tablesProjects.destroy(); And everything seems to be working per the test cases I provided before.
One quick question, by using destroy() instead of empty(), as the refresh is taking place, it shows the mangled table data before it redraws. Is there a way to make sure things are Clea
Take a look at the second example in the
destroy()
docs. It uses empty() afterdestroy()
. As I mentioned above use empty() after you have used any Datatables methods to clean up the table.Kevin
@kthorngren yep I tried that and I get some crazy results. But no worries, this is minor and based on the 2nd example, looks like I may need to split my code up differently. Nevertheless, thanks again for all your help. Which I would've done a jquery search days ago and saw what was causing me all my grief.
Oh well, such is the life of a programmer---live and learn. LOL
@kthorngren hey real quick, now that the refresh stuff is working I am experimenting with using scrollY to have a viewing window, which can essentially function as a fixed header. I've reviewed several examples and my table code matches:
<table id="example" class="display" style="width:100%">
I don't see anything else special yet my table will expand beyond the headers if I open the browser wide enough. And of course, if I turn off scrollY the tables and header/footer expand/shrink together.
I should note I am not using any special css for the table---only the defaults.
Sounds like you are wanting horizontal scrolling using
scrollX
, like this example.Kevin
@kthorngren I am using the example from here: https://datatables.net/examples/basic_init/scroll_y.html
My issue is when the browser window is resized, the header adapts, but the table itself doesn't. Based on this example, I didn't see any special code that was needed to address this, so I thought it was odd. Of course, with no scrollY setting, it all works perfect.
No worries. I am going to close out this thread and stop breaking the rules. I absolutely love what your guys have done with DT and the help you've given me. It is long past time for me to follow the rules you've established and I sincerely apologize for my continued abuse. Won't happen again.
That example is using
"scrollY": "200px"
which is setting the height of the table. From thescrollY
docs:You might be interested in the ScrollResize plugin.
Kevin