0

I have two models : User and Product. One user has many owned_products, and a product belongs to an owner. The products have a available:boolean.

I want to make a list of owned_products that can be toggled from available to unavailable with a button. Here is what I did, using the M. Hartl example :

app/views/shared/_owned_products_list.html.erb

<ol class="products">
  <% @owned_products.each do |product| %>
    <%= link_to(product.name, product) %>
    <%= render 'products/available_form', product: product %>
  <% end %>
</ol>

app/views/products/_available_form.html.erb

<div id="available_button_<%=product.id%>">
 <% if product.available? %>
    <%= form_for(product, remote: true) do |f| %>
      <div><%= f.hidden_field :available, value: nil %></div>
      <%= f.submit t('product.available.undo'), class: "btn btn-small" %>
    <% end %>
  <% else %>
    <%= form_for(product, remote: true) do |f| %>
      <div><%= f.hidden_field :available, value: true %></div>
      <%= f.submit t('product.available.do'), class: "btn btn-primary btn-small" %>
    <% end %>
  <% end %>
</div>

app/controllers/products_controller.rb

    .
    .
    .
  def update
    @product = Product.find(params[:id])
    if @product.update_attributes(product_params)
      respond_to do |format|
        format.html do
          flash[:success] = t('flash.success.product.update')
          redirect_to @product
        end
        format.js
      end
    else
      render 'edit'
    end
  end
    .
    .
    .

app/views/products/update.js.erb

$("#available_form_<%=@product.id%>").html("<%= escape_javascript(render('available_button', product: @product)) %>")

But it doesn't work : The available button is not refreshed at all :

When I click on the available (or unavailable) button, nothing change. If I refresh the whole page, it toggles, regardless the number of clicks...

Do you know where I failed ?

EDIT

OK, I got it, it was a dumb fault : my available_form id was available_button_<%=@product.id%> and not available_form_<%=@product.id%>...

So here is the right one :

app/views/products/update.js.erb

$("#available_button_<%=@product.id%>").html("<%= escape_javascript(render('available_button', product: @product)) %>")
4

1 回答 1

1

我假设您正在使用带有 jquery 和 jquery_ujs 的 rails,让它变得简单:

在 app/views/shared/_owned_products_list.html.erb

<ol class="products">
  <% @owned_products.each do |product| %>
    <%= link_to product.name, product %>
    <%= link_to product.available ? 'turn off' : 'turn on', '#', :class => 'toggle-availability', :'data-id' => product.id %>
  <% end %>
</ol>

在您的 js 脚本文件中:

$.ajaxSetup({
  headers: {
    'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
  }
});    

$(document).on('click', '.toggle-availability', function() {
   var el = $(this);
   var status = el.text();
   $.post('/products/toggle', { id: el.data('id') }, function() {
      el.text(status == 'turn off' ? 'turn on' : 'turn off');
   });
   return false;
});

在控制器文件中:

def toggle
  if request.xhr?
     product = Product.find(params[:id])
     # note here that you should also check the owner of the product
     product.available = product.available.nil? ? true : false
     product.save
  end
  render :nothing => true
end

并在您的 routes.rb 中添加:

resources :products do
  collection do
    get :toggle
  end
end
于 2013-06-20T10:05:31.737 回答