如何使用AJAX更新simple_form输入字段?

时间:2015-05-03 21:15:58

标签: jquery ruby-on-rails ajax simple-form nested-set-model

我有一个 simple_form 输入字段,它是我需要在触发 onchange 事件时异步更新的表单的一部分。

我需要更新的字段显示为选择框,因为它是一个集合。但该集合表示嵌套集模型的记录。因此,当用户选择特定值时,我希望能够使用其子项更新相同的字段,并为用户提供选择任何子项作为相同字段的值的选项。

问题是,如何在不触及表格其余部分的情况下更新该字段。

只是想知道我目前的设置: 表单看起来像这样:



 <%= simple_form_for @product, html: {class: 'form-horizontal'} do |f| %>
     <%= f.input :product_name %>
     <%= f.association :location, collection: @locations, input_html: { data: {remote: :true, url: "/update_locations"} } %>
 <%= f.submit 'Post', class: 'btn btn-default btn-lg' %>
  <% end %>
&#13;
&#13;
&#13;

@product 产品 belongs_to 位置 下, @locations 位置 的集合,每个 has_many 产品 因此使用 simple_form 关联 方法 位置也 acts_as_nested_set

我在我的routes.rb中有这个。

&#13;
&#13;
get 'update_locations'    => 'products#update_locations'
&#13;
&#13;
&#13;

我需要帮助才能完成控制器操作:

&#13;
&#13;
  def update_locations
    @product = Product.new
    @location = Location.find_by_id(params[:product][:location_id])
    @locations = @location.children
    
    # TODO: render code that updates the simple_form field with
    # the new @locations collection
  end
&#13;
&#13;
&#13;

我不确定在上面的控制器应该渲染的局部视图中应该使用什么代码。

1 个答案:

答案 0 :(得分:3)

问题是我不知道如何更新simple_form中的一个元素。 我对使用带有轨道的AJAX非常松懈,不知道你可能同时拥有同一个控制器的HTML和JS部分视图,因此我试图将我的所有代码都放在HTML中,这本身就很麻烦并且反对不引人注目的JavaScript。

绊倒jQuery方法,replaceWith也非常有用。

有了这些知识,我就能完成我的目标。

我创建了一个JavaScript部分视图,它是为响应AJAX调用而呈现的。 partial呈现.html.erb局部视图,该视图使用更新的元素重建simple_form。然后,JS视图从重建的表单中提取更新的元素,并使用jQuery replaceWith()方法替换初始表单中的特定元素,同时保持表单的其余部分不变。

这是JS partial( location.js.erb )的样子:

var updatedLocations = $('#product_location_id', $('<%= j render "updateLocations" %>'))
$('#product_location_id').replaceWith(updatedLocations)

HTML erb partial( updateLocations.html.erb )看起来像这样:

<%= simple_form_for @product, html: {class: 'form-horizontal'} do |f| %>

<%= f.association :location, collection: @locations, input_html: { data: {update_locations: "true", remote: :true, url: "/update_locations"} } %>

<% end %>

控制器:

  def update_locations
    @product = Product.new
    @location = Location.find_by_id(params[:product][:location_id])
    @locations = @location.children
    if @locations.empty?
      render nothing: true
    else
      render partial: 'locations'
    end
  end