Ruby on Rails RJS gotcha.

I know this has been touted in all the tutorials, but I had forgotten it, so I'm assuming that someone else will forget it too.

I had a nice Ajax form, using form_remote_tag(), to update a DIV as per instructions. Having made that work, I wanted to proceed to the next level and swapped out the ERb template for an RJS template. I simply renamed the ERb template, and then stuck an RJS template in between and used replace_html to render the content in the DIV. But it didn't work.
The result was simply plain JavaScript inserted into the page. It looked stupid. The reason was simple; The RJS generated JavaScript wasn't executed in my browser. Having scratched my head, asked some of my friends, scratched some more I decided to retreat back to my documentation. I started browsing through my O'Reilly Short Cut about RJS, and there I had it, highlighted by myself, in an already highlighted box.
This is what the box says:
"Don't Use the :update Option with RJS Calls
Never use the :update option when making remote calls to actions that render RJS templates. The :update option instructs Rails to generate an Ajax.Updater Prototype object instead of an Ajax.Request object. The Ajax.Updater updates a single DOM element with the contents of the HTML response. RJS templates return JavaScript to the browser, which must be evaluated to produce the desired effects"

Of course!
So, changing this:
< % form_remote_tag :update => :my_div, :url => { :action => :my_action },
:loading => "$('indicator').show()",
:complete => "$('indicator').hide()" do % >

into this:
< % form_remote_tag :url => { :action => :my_action },
:loading => "$('indicator').show()",
:complete => "$('indicator').hide()" do % >

Note the lack of :update... it all works! There you have it, have a look into this little gotcha if your RJS JavaScript isn't executed in the browser and you get a nice plain JavaScript displayed in the browser instead of you nicely formatted executed HTML output. :)

No comments: