4

onchangeイベントがトリガーされたときに非同期で更新する必要があるフォームの一部であるsimple_form入力フィールドがあります。

更新する必要があるフィールドは、コレクションであるため、選択ボックスとして表示されます。ただし、コレクションはネストされたセット モデルのレコードを表します。したがって、ユーザーが特定の値を選択したときに、同じフィールドをその子で更新し、同じフィールドの値として子のいずれかを選択するオプションをユーザーに提供できるようにしたいと考えています。

問題は、フォームの残りの部分に触れずにそのフィールドだけを更新するにはどうすればよいかということです。

私の現在のセットアップのアイデアを提供するだけです: フォームは次のようになります:

 <%= 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 %>

@product はLocationに属する新しいProductであり、 @locationsはそれぞれがhas_many ProductであるLocationのコレクションである ため、simple_form関連付けメソッド Location もacts_as_nested_setを使用します

これはroutes.rbにあります

get 'update_locations'    => 'products#update_locations'

コントローラーのアクションを完了するのに助けが必要です:

  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

上記のコントローラーがレンダリングするはずの部分ビューにどのコードを入れるべきかわかりません。

4

1 に答える 1

3

問題は、simple_form 内の 1 つの要素だけを更新する方法がわからなかったことです。また、同じコントローラーに対して HTML と JS の両方の部分ビューを使用できることを知らずに、Rails で AJAX を使用することについて非常に緩い理解を持っていました。 JavaScript。

jQuery メソッド replaceWith に出くわしたことも非常に役に立ちました。

この知識を武器に、私は自分がやろうとしていたことを成し遂げることができました。

AJAX 呼び出しに応答してレンダリングされる JavaScript 部分ビューを作成しました。部分は、更新された要素で simple_form を再構築した .html.erb 部分ビューをレンダリングします。次に、JS ビューは、再構築されたフォームから更新された要素を抽出し、jQuery のreplaceWith()メソッドを使用して、フォームの残りの部分を変更せずに、初期フォーム内の特定の要素だけを置き換えます。

JS パーシャル ( location.js.erb ) は次のようになります。

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

HTML erb パーシャル ( 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
于 2015-05-10T23:55:07.353 に答える