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:
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:
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.
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.
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.
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.
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.