I've searched for a while online and been unable to find anything
concerning this.
I have a controller with an index action, which has an index view.
This view renders the index page but also needs to execute some
javascript to show some data (using effects) when the page loads. I
thought I could just create the view and RJS with the same name and
the RJS would be run after the view, but it seems to stop if a view is
found.
Then I tried to render the RJS template in the controller, but that
takes over and doesn't show the view. Finally, I tried render :update
and that also ignores rendering my html view.
How can I render an html view for an action and then execute
javascript (preferably with an RJS file) when the page loads?
As you have found, there can only be one render.
Not very nice option: with a script tag.
Nicer option: have your index file load a separate js file that observes dom:loaded and fires off any stuff you need from there. rjs won't help you much here (unless you generate the javascript on the fly), but to be honest I've come round to the feeling that if you're generating javascript you might as well remove the middleman. Writing js with a library like prototype is actually quite fun.
Is it possible to stub out the included code, perhaps via a helper,
and have it auto-included in the layout without actually modifying the
page or layout?
I'm trying to do something very similar to what Tim is, but I want it
to eventually be a plugin and ideally it just appends the javascript
stuff at the bottom of every page without the app developer having to
do anything other than install the plugin (and maybe set an
environment variable).
I suppose you can do the previously mentioned solution (read: hack) and do this:
At the bottom of your rhtml file you can use update_page_tag run
generated javascript in a block that acts like an rjs file
For example,
…
…
Hide This Stuff
<%= update_page_tag do |page|
page.alert("JavaScript Ran On Load!")
page["hide"].hide
end %>
But instead of doing an alert, do page << “myfunc();” and put myfunc() in your .js file so that you can reuse it. I haven’t heard of a way to do this with an actual .rjs file yet, but that would be the ideal solution.
in a view file seems to do the trick. The second line is needed because the rjs renderer sets the mime type to text/javascript (unless it is already set, so you may be able to do without it if you are in a respond_to block or something like that).