开发者

link_to remote=>true not updating with ajax

Using rails3 and prototype (rails.js)

I have a simple list of products with edit and delete links as images. When deleting a product, the list is not updated. Refreshing the pa开发者_如何学运维ge shows that the product has indeed been deleted.

/app/views/products/list.rhtml

<div id="product_list">
  <%= render :partial => 'list'  %> 
</div>

/app/views/products/_list.rhtml

<%= link_to image_tag("delete.png"), { :controller => 'products', :action => 'destroy', :id => product }, :method => :delete, :confirm => "Are you sure?", :remote => true %>

/app/controllers/products.rb

  def destroy
    Product.find(params[:id]).destroy
    @products = Product.all
  end

/app/views/products/destroy.rjs (not sure what to do with that...)

$(document).ready(function() {
    $("#product_list").html("<%= escape_javascript( render(:partial => "list") ) %>");
});

So the remote link seems to work fine. I'm not sure how to use the ajax callback to update #product_list

I tried to put the following in the head of the page:

$(document).ready(function(){
  $('#product_list').bind("ajax:success", function(evt, data, status, xhr){
      alert('hello');
    })
});

But it's not executed (that's probably not a valid code for prototype) and I wouldn't know anyway what code to put inside so that my list gets updated after destroying a product

Any help (other than "use jQuery") is greatly appreciated!

EDIT: Here is the server log for the delete action (after I moved the javascript above to destroy.js.erb)

Started POST "/products/destroy/3" for 127.0.0.1 at .....
Processing by ProductsController#destroy as JS
Parameters: {"_"=>"", "id"=>"3"}
[1m[36mProduct Load (0.0ms)[0m  [1mSELECT `products`.* FROM `products` WHERE (`products`.`id` = 3) LIMIT 1[0m
  [1m[35mSQL (0.0ms)[0m  BEGIN
  [1m[36mSQL (0.0ms)[0m  [1mDELETE FROM `products` WHERE (`products`.`id` = 3)[0m
  [1m[35mSQL (78.1ms)[0m  COMMIT
  [1m[36mProduct Load (0.0ms)[0m  [1mSELECT `products`.* FROM `products`[0m
Rendered products/destroy.js.erb within layouts/standard (31.2ms)
Completed 200 OK in 312ms (Views: 62.5ms | ActiveRecord: 78.1ms)

Processing by ProductsController#destroy as JS so the remote link works

[36mProduct Load (0.0ms)[0m [1mSELECT products. FROM products* The @products = Product.all is executed

Rendered products/destroy.js.erb within layouts/standard the javascript fie is rendered

So now I guess it's a problem with the javascript code:

$(document).ready(function() { $("#product_list").html("<%= escape_javascript( render(:partial => "list") ) %>"); });

Is that kind of code supported by prototype? I don't use jQuery...


Found the answer on my own:

/app/controllers/products.rb

  def destroy
    Product.find(params[:id]).destroy
    @products = Product.all
    respond_to do |format|
        format.js { render :layout=>false }
    end
  end

/app/views/products/destroy.js.erb

$("product_list").update("<%= escape_javascript(render(:partial => "list")) %>");

Why is there NO tutorial, code example or anything clear about the ajax thingy in rails3? I had to use code parts from 5 different blogs, forums and casts, and mix them all together until I find the right combination... sigh


on repecmps lines,

just insert :content_type to represent part of content downloaded, like this:

format.js { render :layout=>false, :content_type => 'application/javascript' }

with complete part of repecmps responses:

def destroy
  Product.find(params[:id]).destroy
  @products = Product.all
  respond_to do |format|
      format.js { render :layout=>false, :content_type => 'application/javascript' }
  end
end

/app/views/products/destroy.js.erb:

$("product_list").html("<%= escape_javascript(render(:partial => "list")) %>");

and, I found this to night.


I think your destroy action is doing too much, as it is destroying the product and list all the products. You could do something like:

/app/controllers/products.rb

class ProductsController < ApplicationController
  respond_to :html, :js

  def destroy
    @product_id = params[:id]
    Product.find(@product_id).destroy
    respond_with do |format|
      format.html { redirect_to posts_path }
    end
  end
end

/app/views/products/destroy.js.erb

$("#product_<%= @product_id %>").remove()

As long as your product element in the index uses something like dom_id, here's an example:

<ul id="products">
  <% @products.each do |product|
    <li id=<%= dom_id product %>>...</li>
  <% end %>
</ul>

This way your destroy action will only destroy the intended product, and if the client has no JS it fallback the HTML request which will redirect to the products index which will be updated accordingly.


Hum... I'm going to try to help you.

Are you sure after clicking on the delete link, the request is handled as JS ? Check on the log.

Is you file "app/views/products/destroy.rjs" is rendered ?

Rjs doesn't exist anymore in rails3. The new name is UJS.

Try to rename the file to destroy.js.{haml or erb}

Is it better ?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜