*.js file not rendered when requesting from <a> HTML element

Hello people, I'm wondering why this is not working. I have some plain JavaScript wrote on mycontroller.js , works like a charm; I'm listening to few events of the related view and works. I've been writing some code, testing it manually refreshing the page in the browser and goes ok. The problem arise when I come to this view from another view. I have a side-bar, when I click an <a> element it calls another action and render another view. When I click the link which takes me to an action of `mycontroller` controller the JavaScript work doesn't work, doesn't get executed. Why is this? I'm listening to the events by:

window.onload = function() {    document.getElementById('my_element').onclick = function() {      // do stuff...    }

   // another listen... }

I'm wondering if I should use another event more than window.onload , perhaps that doesn't get triggered when I come to this specific view from an <a> HTML element. Do you have any clue about what's happening? Thanks for your time, I appreciate it.

It’s hard to say, you would need to follow it in a browser that has tools for that such as firebug in Firefox. Chrome and Safari also have good developer tools. My guess would be turbolinks. If you are using Rails 4, turbolinks is installed by default. Turbolinks regenerates the page’s content without loading a new page. Therefore, document.ready and window.onload aren’t triggered. You need to use one of turbolink’s events, such as page:change. See documentation at the following:

https://github.com/rails/turbolinks

If that’s not it, I would need more information.

I will take a look to that link in my afternoon, interesting thing what you say, thanks for the hand, I appreciate it.

What exactly (please paste code examples) by “comes to this view from another view” ?

If the page is reloaded check to make sure your onload handler is re-attached correctly (you can do this with simple debugging or console statements inside of your onload function)

If you have some kind of ajax setup (like some of the default Rails stuff), then parts of the page might be getting replaced with new HTML content (Like your my_element). When that happens, the HTML is replaced and the new html elements do not have the click handler attached to them (and your onload is not re-run).

To keep things the way they are, try using jQuery 's on method (http://api.jquery.com/on/), which you should attached to a parent of the object that is getting replaced by ajax – not the actual link itself.

Better yet, think about learning Backbone, Ember, or Angular. The way you are working with Javascript works OK in very tiny apps, but breaks down quickly in larger apps with a lot of client-side interactivity. Personally, I haven’t written javascript in the style you are writing it (big, global class-bsaed targets that attach click handlers during the window’s onload) since about 2009.

-Jason

If you are using turbolinks you have to re-attach all your click handlers after the page content is replace, as discussed with detecting the page change event.

Like I said, in a small app you will get away with this but in a larger app you will drown in a nightmare of page change event binding and handler attachment bugs. This is why generally Javascript developers I know stay away from this style of coding and prefer a more robust think-client approach like the ones I mentioned. Obviously, detecting a change event may just be a small fix and learning a whole new way to write code is a bigger task.

Jason Fb wrote in post #1150072:

What exactly (please paste code examples) by "comes to this view from another view" ?

I'm in an HTML page, I click an anchor HTML element(<a>) which takes me to another HTML page.

If the page is reloaded check to make sure your onload handler is re-attached correctly (you can do this with simple debugging or console statements inside of your onload function)

It's not re-attaching. I'm thinking that turbolinks has something to do.

If you have some kind of ajax setup (like some of the default Rails stuff), then parts of the page might be getting replaced with new HTML content (Like your my_element). When that happens, the HTML is replaced and the new html elements do not have the click handler attached to them (and your onload is not re-run).

I don't know how can I check if this is happening?

To keep things the way they are, try using jQuery 's on method (.on() | jQuery API Documentation), which you should attached to a parent of the object that is getting replaced by ajax -- not the actual link itself.

Better yet, think about learning Backbone, Ember, or Angular. The way you are working with Javascript works OK in very tiny apps, but breaks down quickly in larger apps with a lot of client-side interactivity. Personally, I haven't written javascript in the style you are writing it (big, global class-bsaed targets that attach click handlers during the window's onload) since about 2009.

If you are using turbolinks you have to re-attach all your click handlers after the page content is replace, as discussed with detecting the page change event.

I'll take a look at how turbolinks work.

Like I said, in a small app you will get away with this but in a larger app you will drown in a nightmare of page change event binding and handler attachment bugs. This is why generally Javascript developers I know stay away from this style of coding and prefer a more robust think-client approach like the ones I mentioned. Obviously, detecting a change event may just be a small fix and learning a whole new way to write code is a bigger task.

Thanks for the advices Jason, very helpfull.

Try putting debugger or console.log(“xyz”) inside of your onload handler. If you don’t see it break at the breakpoint or console output “xyz” when you click to a new page, then it isn’t re-attaching.

I’m actually not the person to ask about using turbolinks (since I’m not a big fan), but it sounds like there’s a way to detect the change event and re-call the function that makes the attachment.

-Jason

Yes, the issue was caused by turbolinks. What I did to fix it is very simple, I've added the atribute 'data-no-turbolink' => true to the link_to() which takes to the view with JS attached. Works like a charm, thank you all for the help.

I wish there was some way to favorite these nuggets of gold in Apple Mail...

Thanks!