Plugin attaches itself to incorrect DataTable instance(s)
Plugin attaches itself to incorrect DataTable instance(s)
Update: Switch to 2nd post to get the more accurate details.
This one might be difficult to explain..
Im using my new Live Ajax Plugin to monitor any changes in the ajax.url
source of a DT instance.
This particular DT instance uses child rows, and in those child rows lies other DT instances, (which do not use the Live Ajax plugin). When these child rows are expanded, the "Child DataTable Instances" are created, and when the rows are collapsed, those child DT instances get destroyed via destroy()
.
Now, the Live Ajax Plugin monitors the destroy.dt
via one()
for the table that it was initiated on, when it sees that the table was destroyed, it will then quit monitoring the AJAX source for changes.
Problem: When the Child DT Instances are destroyed (due to the containing child row being collapsed) within the "parent" table, somehow, the destroy.dt
monitor within the Live Ajax Plugin sees that and quits monitoring the AJAX source, even though its a different table being destroyed.
Has anyone ever ran into this? The destroy.dt
attaches to the API that was created here within the plugin, but that shouldn't cause any issues would it?
This question has an accepted answers - jump to answer
Answers
Oh, I was able to create a JSBin instance of it.
To Replicate..
When you run the above steps, you should get an alert, which is generated by the pluginTest code at the top of the JS. The alert is generated on line 17, which is executed by the
destroy
on line 16. Thatdestroy
event should be tied to an API instance that was created on line 13, that API reference should reference the Parent Table..Heres the weird part: That alert that fires from within the
pluginTest
code, should only fire whenever the table that haspluginTest
initiated on it gets destroyed, which you can see on line 32 that I'm initiating the DT instance with pluginTest on the Parent Table (#example1
), however, when I destroy the Child Table (#childTable
), thedestroy
gets fired...Basically.. You should never see that alert, as it should only be fired when the Parent Table gets destroyed, and as you can see on line 55, I'm destroying the Child, not the Parent...
Im including the JS code below, so you can see what line numbers in referencing, since the JSbin doesnt include line numbers
@allan - Do you think you can help at all with this?.. Thanks man
So the issue here is the bubbling of the events. Because DataTables uses jQuery to trigger events, and jQuery in turn uses synthetic DOM events, the events will bubble up through the document.
At the moment, to prevent this you would need to add a destroy event listener to the child table and then call
event.stopPropagation()
: http://live.datatables.net/rabijuku/3/edit . That will stop the event bubbling up to the parent table.Another option is to add a check into the destroy event handler to make sure that it is actually operating on the expected table.
Without question this is a bug in the current design. The next major version of DataTables is going to rework the events and only a few (
init
is the only one I'm certain of) will be allowed to bubble.Allan
Sucks its a bug, but good to know that it wasn't just a bug I couldnt figure out. This one had me banging my head against the wall for a while.
This is what I was tempted to do.. Probably just best to check for the ID I suppose. Should I just change it from
one()
toon()
, then check if the ID of the table being destroyed is the same as the ID of the table tied to the API object created on line 13? Then once I allow it to destroy the table, since the events are just regular jQuery events, I can detach the event listener right? (If so, would you suggest .detach() or .unbind()? Guessing the former)Ill probably do the other approach, since thats easier to control via the plugin, and it wouldn't require people to add an event handler to fire the
stopPropagation()
themselves.Thanks though, thats a good thing to know!
$().detach()
will remove an element from the DOM without removing tis event listeners, while$().unbind()
will remove event listeners from an element. They do different things.$().off()
is what I normally use to remove event listeners.Allan
Ok, is that the best route then?
@allan - How would I determine if whats being destroyed within..
I tried to check if it was the correct table via
$(api.table().node() ).attr('id'));
, but that always returns the correct (Parent) table, not the DT instance in the child rowgives you the table id.
Allan
perfect!! thanks man