responsive-resize event will be infinitely triggered
responsive-resize event will be infinitely triggered
Right now, I'm working on a responsive Datatable, where I want to hide a column while showing the table on a desktop and on a landscape table. The row should be shown only on mobiles and portrait tablets.
Here is a small test case:
https://jsfiddle.net/jmeile/n4pkdau8/30/
If you debug the Fiddle using the Developer Tool from Mozilla or Chrome and put a break-point inside the responsive-resize handler (line 34 in the js iFrame), then you will see that that event will be infinitely triggered.
To try it, just open this link:
https://jsfiddle.net/jmeile/n4pkdau8/30/show
Press: Run, open the iframe in a new tab, press F12 and put the break-point.
I saw that this behavior will stop if I comment the lines: 24 and 27 from the jsFiddle. Basically this two:
data_table.columns( [3] ).visible( true );
data_table.columns( [3] ).visible( false );
So, this two lines trigger the event again and that's why it will be kept running infinitely.
I really need those two lines since the idea is to hide the age column while on a desktop or a landscape tablet and show it on the other devices.
I tried this things without any success:
* Stop event propagation with: e.stopPropagation();. This is the current implementation
* Adding a global variable, but it seems that inside the event handler that global variable can't be read. It says always: undefined
From this Stackoverflow answer:https://stackoverflow.com/a/1922012, I tried everything:
* Appending a boolean flag to the e.data -> It keeps running
* Disabling the event handler with .off(), then re-enabling with: .on(). It will run only once, so, it won't be re-enabled.
* Adding and removing a css class -> It keeps running
So, basically what I need is to temporary disable the responsive-resize event. Any idea on how to achieve this? Is there perhaps a better way of achieving what I want?
Best regards
Josef
Answers
Maybe try invoking the event handler from inside the
show_hide_column
function and use jQuery one() instead of.on()
, something like this:Maybe you can use Responsive class logic to achieve what you want.
Kevin
Hi Josef,
The easiest way to do that is to use the
mobile
andtablet-p
classes on that column.However, that isn't what your code is currently doing - rather you are attempting to show a column if any others are hidden.
For that, we could hijack the
dtr-control
class: https://jsfiddle.net/CloudTables/4bj9avcn/ . You might need to disable the show / hide click event handler, but is that more inline with what you are looking for?The
responsive-resize
event is a bit tricky because it is async - we have a small debounce in so it doesn't just trigger rapidly, but it makes this sort of thing a little more complex!Allan
@kthorngren Regarding your answer: as far as I know the .one() handler will be executed only one; however, I need to show/hide the column each time that the user enters or leaves the responsive view, which on my case it would be the mobile and tablet-p modes; the other modes will show the full table.
Regarding the class logic, I already tried to set the age column to "mobile" and "table-p", but that's not the result I want. See the next screenshots and you will see why I don't want that.
@allan I tried with the dr-controll class and assigned it to the "age" column, which is the one I actually want to hide or show according to the view, but it is not working as I want, see: https://jsfiddle.net/jmeile/kezo36n0/5
On desktop and tablet-l modes it is doing what I want: hide the age column. However, on mobile and tablet-p modes, I want that column to be shown as a detail and not as a column. This is what your suggestion does:
But this is what I really want:
My original code is working; however, that handler will be triggered infinitely and I think it slows the rendering of my table and sometime the pagination won't work.
I guess, I will try this with the $(window).resize event instead. I will have to see the window dimensions. I don't like this solution because I will have to hard code the breakpoint dimensions, but as I see it seems to be the only one that seems to work
MMM, my comments got blocked again
I guess your system doesn't like when I edit my answer several times. Anyway, just for the records: I will try now the $(window).resize event. I don't like it since I will have to hard code the viewport dimensions, but it seems that it is the only thing that will work.
Ok, I solved the problem with $(window).resize. The best thing is that I don't have to hard code the dimensions of the viewports. I only used the function: responsive.hasHidden(), which is really what I want to check. Here the final version:
https://jsfiddle.net/jmeile/n4pkdau8/74
I don't know if this is the best approach, but at least the event handler won't be infinitely triggered.
Nice, thanks for reporting back,
Colin
There is only one thing that I would like to know. On lines 22 and 23, I'm doing this:
This is inside a function called: show_hide_column. I tried to work with a global variable, but it tells me that that variable isn't defined. Is there any better way of solving this? I'm really concern about line 23: would that line recreate the DataTable each time or will just call the one that is already on memory?
That's because the
my_table
variable wouldn't be defined until the table initialises, but yourshow_hide_column()
function is called ininitComplete
, before that initialisation completes. What you've done is fine, as the DataTable has been initialised, callingDataTable()
without any options just returns the existing table. You could do a global variable like this perhaps, but it's only a couple of lines shorter,Colin
The code in your example looks like this:
The variable
my_table
should be within scope and available in yourshow_hide_column
function. The two lines (22-23) you are asking about can be combined into one and since you have the Datatable initialized they are just getting an instance to the Datatable API as described here.Kevin
@colin Thanks for your example, it works. One more question: how do you get the jquery object from the DataTable instance?
@kthorngren This is not entirely truth. I already tried with my_table, but it will fire this exception:
So, it doesn't work when it first gets called in initComplete. Colin already explain why this happened:
You may try it on my last test case and see it by yourself:
https://jsfiddle.net/jmeile/n4pkdau8/79/
Best regards
Josef
Yep, I agree with that. Forgot you were calling it from
initComplete
.Kevin
Regarding my last question, I just figured out how to do it:
Yes, I could just do: $('#example'), but I don't want to hard code the id inside the function, so that it works for more DataTables. Another option would be to add the id parameter, but why to do this when everything is already available inside the DataTable object
Yep, I was just about to reply and say
table().node()
was the way to go.Colin