views:

370

answers:

3

I have a controller and a view (no ActiveRecord for this one). The controller calculates the current time in several places in the world and the view presents them.

I'd like to add a button that will make the clocks update. Adding a regular button which refreshes the whole page works fine, but I'd like to do that asynchronously using AJAX. I've tried to use form_remote_tag, but then nothing happens because nothing gets refreshed...

How do I do that?

(BTW, I'm doing that for learning rails. There's no real need or requirement)

My code: The controller interesting part:

def index
  utc_time = Time.now.getutc
  @clocks = []
  @clocks << ["USA - New York", utc_time - 60*60*5]
  @clocks << ["England - London", utc_time]
end

The view interesting part:

<%= javascript_include_tag 'prototype' %>

<div id="clocks_div">
<% @clocks.each do |city, time| %>
  <b><%=h city %></b>: <%=h get_formatted_time(time) %>
<br/>
<% end %>
</div>
<br/>

<% form_remote_tag do %>
    <%= submit_tag "Refresh!" %>
<% end %>

Thanks for the help

A: 

I think you have to pass to form_remote_view the name of the div you want to update and the action/controller you want to use. Try something like this:

<% unless params.has_key? "refresh" %>
 <% form_remote_tag :update => "clocks_div", :url => { :action => :index } do %>
  <%= hidden_field_tag 'refresh' %>
  <%= submit_tag "Refresh!" %>
 <% end %>
<% end %>

NOTE: Although this should work, it may be convenient to move the template for the clocks_div into a partial and to render it through a separate action

And
+1  A: 

Move the contents of the clocks_div into its own partial (but not the div itself). Then in the index page you can use a link_to_remote, button_to_remote, or even periodically_call_remote to update the div.

So:

<% periodically_call_remote :update => "clocks_div", :url => { :action => :refresh } %>

or

<%= button_to_remote "Refresh", :url => { :action => :refresh }, :update => "clocks_div" %>

Then in your controller do something like: (I've added some refactoring here)

def get_clocks
  utc_time = Time.now.getutc
  clocks = []
  clocks << ["USA - New York", utc_time - 60*60*5]
  clocks << ["England - London", utc_time]
  clocks
end
private :get_clocks

def index
  @clocks = get_clocks
  # Renders the full index page by default
end

def refresh
  render :partial => "clocks", :layout => false, :locals => { :clocks => get_clocks }
  # Renders only the clocks partial with the clock values
end
Daemin
A: 

If u dont want the view side updation ,, u can do that from the action side to by rendering update

Eg.

render :update do |page|
page[:clocks_div].innerHTML = render :partial => "controls/tag_list"
end

Arpit Vaishnav