Close and Go BackBack to Viget

Getting Started With RJS in Rails

Patrick Reagan
Patrick Reagan, Development Director, November 22, 2006 One of the features of Rails that makes it a great framework for building the next generation of "Web 2.0" applications is its tight integration with the script.aculo.us JavaScript library. What this means for your application is the ability to dynamically update the display based on the results of an action (in this case '/task/mark_complete'):
def mark_complete
  begin
    @task = Task.find(params[:id])
    @task.task_status_id = TaskStatus::COMPLETE
    @task.save
  rescue ActiveRecord::RecordNotFound
    render :nothing => true
    return
  end
  render_text @task.status.description
end

Adding this code in a view template is all we need to have our display automatically update:

   

Status: <%= @task.status.description %>

<%= link_to_remote 'Mark as Complete', :update =>, 'task-status-' + @task.id.to_s, :url => {:controller => 'task', :action => 'mark_complete', :id => @task %>

This works great for those times when we only need to update a single DOM element on a page. What about when we need to update multiple pieces of content on the same page? One solution that has worked quite well for us is the use of RJS templates in Rails.
To take our simple example a bit further, let's say that when we mark a task as complete, we want to update some general task list reporting information and highlight the current task after the update occurs. Here is our status information and task listing in the view:

  Completed:
  <%= Task.completed_count %> task(s)
Remaining: <%= Task.remaining_count %> task(s) <% for task in @tasks %>
Task: <%= h task.title %>
Status: <%= task.status.description %>
<%= link_to_remote 'Mark as Complete', :url => {:controller => 'task', :action => 'mark_complete', :id => task} %> <% end %>
This is where the RJS template comes into play – we'll write the Ruby code to update the display and then wire it into our action. This content will go in 'views/task/_update_tasks.rjs':
page.replace_html('tasks-completed', Task.completed_count)
page.replace_html('tasks-remaining', Task.remaining_count)
page.replace_html('task-status-' + @task.id.to_s, @task.status.description)
page.visual_effect(:highlight, 'task-item-' + @task.id.to_s, :duration => 1.0)
Now, we'll go back to the action and wire it up to use our new RJS template. The 'render_text' line is all that's changed from the original example – I'll include the full sample for clarity:
def mark_complete
  begin
    @task = Task.find(params[:id])
    @task.task_status_id = TaskStatus::COMPLETE
    @task.save
  rescue ActiveRecord::RecordNotFound
    render :nothing => true
    return
  end
  render :partial => 'update_tasks'
end
That's all there is to it, now when you flag a task as completed you'll get the feedback immediately in your browser.
blog comments powered by Disqus

We're the Developers

at Viget Labs. We write about web development trends, tips, best practices, industry events, and our projects — all with an emphasis on Ruby on Rails.

Contact Us

Have any questions, comments, ideas, or secrets to share? Let us know.


How many hours in a day?

Sorry, you need to have Javascript enabled to use this form. (Don't blame us, blame the spammers!) If you'd like to contact us, please visit our Contact page.