I have some javascript that puts click handlers on buttons (for instance). Since those buttons don't exist when the user first visits the app at, say, the "Home" page, I listen like so: $(document).on('turbolinks:load', initializeButtons);
. This works when the user goes from the "Home" page (where the buttons don't exist) to the "Search" page. When the "Search" page is loaded, initializeButtons
runs again when these buttons do exist.
On the "Search" page, after the user clicks "Search", a POST is issued and turbolinks updates the page using its magic which replaces the buttons that were initialized. How do I listen for this POST event so that I can reinitialize the buttons (and other initialization) that needs to be done?
To initialize your buttons, use $(document).on(event, selector, func)
; for instance, $(document).on('click', '#add_row_button', add_row_func);
. Using this method, any time a 'click'
(sicut exemplar gratia) event, jquery will check the DOM for the selector you gave and route the event to the proper element at the time of the event rather than at the time of registration. This way, your event handlers aren't tied to the elements that Rails's unintrusive javascript implementation (more on this later) will be removing, and the new elements will be found by the dynamic event handling jquery does.
Regarding the initialization of other plugins, the first thing to note is that no POST is issued. Your <link_to ... remote:true/>
links are actually issuing XHR requests. After such a request and after Rails's unintrusive javascript implementation replaces your elements, you will need to re-initialize them. As max mentions in his answer, turbolinks isn't involved in this part of the page lifecycle. Instead, you should listen for ajax:complete
, for example, on the submitting element (id est <a>
in this case). Of course, it's not that simple. If you listen for ajax:complete
, the event handler will never be invoked because by the time that event fires, your elements have already been replaced. Instead, listen for ajax:start
, then register for the complete
event directly on the XHR. That way, after your anchor elements are replaced, your event handler is tied to the XHR which still exists. Something like this should do:
$(document).on('ajax:send', '#parent-container > a', (event, xhr) => {
xhr.complete(()=>initializeTheStuff());
});