Simple Ajax And Inline Javascript With Rails

2 minute read

This is a seriously old post. I’d probably not bother reading it, but I keep it here for nostalgia.

I’ve noticed a lot of people asking questions about ajax, rjs, scriptaculous and other whizzy cool effects lately. So I thought I’d document a couple here so there’s less confusion about some of the simpler effects. I’ve included an element toggle on a hyper link, a simple div that updates with data from an action using link_to_remote, and others. Enjoy.

Let’s continue…in the style of Gordon Ramsay:

Prepare

All of these examples assume you have included the default javascript files in your application.rhtml file:

<head>
  <%= javascript_include_tag :defaults %>
</head>

Toggle

The first of our simple effects is going to have to be the simple toggle (hide/show) of a div element. There is no remote call used in this, it simply uses javascript (generated by our ruby code) to show and hide a element of our choice.

<%= link_to_function "toggle with my div", "Element.toggle('to_toggle')" %>
<div id="to_toggle">
  Now you see me, now you don't!
</div>

Remote

Next we’re going to fire an action from a link_to_remote and then update a list of items on the page, this involves multiple code pieces in different files, keep up.

<!-- app/views/words/index.rhtml -->
<ul id="sentence">
  <li id="word_1">baby</li>
  <li id="word_2">unzip</li>
  <li id="word_3">my</li>
</ul>
<%= link_to_remote "WHAT?!?", :url => { :controller => 'words', 
                                        :action => 'update' }, 
                              :loading => "Element.show('loading')" %>
<div id="loading" style="display:none;">Loading...</div>

<!-- app/controllers/words_controller -->
def update
  @word = "laptop bag!"
  return if request.xhr?
end



<!-- app/views/words/update.rjs -->
# hide the loading text
page.hide 'loading'
# insert a new li into the element with an id of sentence
page.insert_html :bottom, 'sentence', 
  "<li id='word_4'>#{@word}</li>"

Notice how we use the same name for our rjs file as we did for the action we called, and then we ask the controller to return if the request was an xml http request (which is what ajax uses). This way if we want to do both rjs and standard requests with the update action we can.

I also demonstrated the use of a loading div here, but you could use a loading image as well, like a spinny circular thing or dots…or whatever takes your fancy.

Highlight

Let’s modify the above example to highlight the new element when it arrives, this one’s far too easy. Add this to the bottom of update.rjs:

page.visual_effect :highlight, 'word_4', :duration => 3

Now when the element is added, you’ll have your attention drawn to it. The duration can be left off because it’s optional and defaults to 2 seconds, I just wanted to make you aware that it’s there.

Blind

Again, modify our existing call and make it slide down instead of just appear, change the update.rjs to this:

# hide the loading text
page.hide 'loading'
# insert a new li into the element with an id of sentence
page.insert_html :bottom, 'sentence', 
  "<li id='word_4' style='display:none;'>#{@word}</li>"
page.visual_effect :blind_down, 'word_4', :duration => 2

We added to our li item a style of display, and set it to none. This is standard inline css markup, so when the item is added to our page it’s hidden. Then we use the blind_down visual effect to slide it down with a duration of 2 seconds.

Simmer

I hope this helps all the ajax beginners get started with effects you can play with, be sure to check out the Rails api documentation for more scriptaculous effects.

Any questions boys and girls?

On a side note, inline javascript is bad. Unobtrusive is king.