简体   繁体   中英

Updating partial view with AJAX

I have page with many images, each of which has an associated text box used to submit tags on that image. Each image and text box is rendered through a partial view. Currently I am able to update tags and everything works correctly through a full page refresh. I would like to be able to do all this through AJAX, but I'm having some trouble with it.

Here is the form code in the partial view:

<%= image_tag image.src %>
<%= form_tag :controller => "images", :action => :update_tags, :remote => true, :image => image.id do %>
  <td><%= label_tag "Tags:" %></td>
  <td><%= text_field_tag :tags, image.tags %></td>
  <td><%= submit_tag "Submit" %></td>
<% end %>

And the main form that calls the partial:

<% @images.each do |image| %>
  <div id="image_#{image.id}">
    <%= render :partial => "image_tag", :locals => { :image => image } %>
  </div>
<% end %>

In the:update_tags method in the controller I add the image's tags to the DB and then want to reload that image's partial view.

Here is the controller's redirect code:

respond_to do |format|
  format.js
  format.html { redirect_to :back, :remote => true }
end

And the update_tags.js.erb:

$("#image_#{image.id}").html( "<%= escape_javascript(render :partial => 'image_tag', :locals => {:image => image} ) %>" );

It currently is working functionally, but no AJAX magic happening. I'm still learning Rails and jQuery, so any help would be greatly appreciated. I think I've included all relevant code, but let me know if there's anything else I should provide. Thanks!

One thing I see wrong is that you can't use #image for each of your image divs (assuming there are many of those on the page).

Anytime you use an element ID like that, it has to be unique to the entire page, otherwise jQuery will find the first instance of #image and then stop. So, you need to make each of those image ID's unique by possibly including a model ID, etc. so it would be #image_1 #image_2 etc.

Another thing is, why do you have

format.html { redirect_to :back, :remote => true }

in the controller action for the AJAX call? AJAX is only going to return format.js so it seems unnecessary. Maybe I'm misunderstanding something there.

The rest of your code looks correct. You may want to check your Rails server log to make sure your update_tags.js.erb file is being rendered during the call. If it is, then you have a javascript error.

Update: You need to also make sure you have this installed so Rails can trigger your AJAX calls properly https://github.com/rails/jquery-ujs

You don't need the HTML to be rendered if you're doing AJAX. By default, it will render controller_action_name.js.erb since it's an AJAX call versus a browser call. You should see something like this in the Rails server output:

Started PUT "/images/1/update_tags" for 127.0.0.1 at 2011-07-16 09:33:20 -0400
  Processing by ImagesController#update_tags as JS
  Parameters: {"image_id"=>"1"}
  Image Load (1.6ms)  SELECT "images".* FROM "images" WHERE "images"."id" = 1 LIMIT 1
  CACHE (0.0ms)  SELECT "images".* FROM "images" WHERE "images"."id" = 1 LIMIT 1
Rendered images/update_tags.js.erb (11.3ms)
Completed 200 OK in 346ms (Views: 23.7ms | ActiveRecord: 1.7ms)

On this line <div id="image_#{image.id}"> you can't do normal Ruby string interpolation bc you're inside a rails view. Needs to be <div id="image_<%= image.id %>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM