Rails 3: Simple AJAXy Page updates?
Asked Answered
S

6

13

I can't believe I've been looking four hours for this simple task, but I have.

In Rails 2.3, I could replace one section of a page with this simple code:

render :update do |page| page.replace_html "div_id", :partial => "new_content",... end

In Rails 3, Ryan Bates has me writing entire new javascript functions, switching from Prototype (rails default) to jQuery, and otherwise not enjoying life. The other tutes are no more straightforward.

What am I missing? How do we replace a <div> these days?

Stentor answered 25/10, 2010 at 15:45 Comment(0)
S
12

Thanks, guys. The official answer seems to be that, yes, the team felt simple is the enemy of good and made it more complicated.

The first key is to create a .js.erb file NAMED for the method CALLING the ajax update. So if the index method handles the update, put the raw javascript in index.js.erb. This goes in the views folder.

Second, the code that worked in index.js.erb was

m = $('list_users');    
m.innerHTML = "<%= escape_javascript(render :partial => "reload_users") %>";

Then to make the call, add in the respond_to block of the controller method, add:

format.js

Finally, the calling view has:

<%= link_to "Update User List", @reload_users_path, :remote => true %>

By the way, supposedly all the old pages using page.replace will work if you install a plugin. The plugin download page suggests that it broke in the last releases of Rails 3 and has not been fixed. Also, various bloggers will come to your home and birch-switch you if you use it.

Stentor answered 26/10, 2010 at 18:7 Comment(1)
I'm not sure why some rails developers think .replace_html is "inline javascript". It is RPC (Remote procedure call) a solid design pattern. They just need to covert the backend to a RPC client/server messenging service and make the client side API library agnostic.Insert
R
4

The whole RJS stuff makes the javascript inline and makes the dom very obtrusive. Also, by avoiding inline javascript you could open up other possible ways of optimizing you javascript by compressing and caching those files in browser. Thats the reason why RJS is getting out of scope from rails 3. A little bit of getting around with jQuery or Prototype for a day should get you on gears with these kind of small stuff and will help the project on long run.

Rog answered 25/10, 2010 at 16:28 Comment(0)
P
1

Do you still have jQuery in there? I'd recommend it over Prototype any day...

If it's still there you can just use the following in your Javascript:

$.get("<%= url_for path/to/partial %>",
      function(response) {
        $("#div_id").html(response);
      });

This gets the partial via AJAX and just dumps it into the div with id div_id.

Hope this helps!

Phylloxera answered 25/10, 2010 at 15:51 Comment(2)
No, just trying to update to Rails 3 for now, not wanting to learn jQuery today. :-) page.replace_html seemed simple and effective enough.Stentor
Darn, ah well! Unfortunately I haven't used RJS or Prototype in so long that I've forgotten how to use them!Phylloxera
E
0

I'm not even sure you need to make an AJAX call to load that partial. I believe that in a js.erb file, a call to render(:partial => object_or_path) will just return a string with all the html, which you can wrap in a jQuery object and append. Example:

$('#div_id').html($('<%= render :partial => @object %>'))
Elli answered 25/10, 2010 at 16:15 Comment(0)
E
0

As far as I know, along the same line as the answer above, you can do something like this in your template:

<%= link_to "Update User List", @reload_users_path, :remote => true %>

And in controller, do this:

respond_to do |format|
  format.js {
    render :text => "alert('reloaded')"
  }
end

This way you can have controller "execute" client side JS much the same as as render :update used to do. This is equivalent to doing the following in Rails 2:

render :update do |page|
   page << "alert('reloaded')"
end

Is there any reason why this approach is not advisable?

Eckard answered 3/4, 2013 at 6:29 Comment(0)
H
-2

Try this:

page.call "$('#div_id').html", render(:partial => 'new_content')
Hazen answered 26/1, 2011 at 23:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.