2015-05-03 52 views
4

我有一個simple_form輸入字段是一個窗體的一部分,我需要在觸發事件時異步更新。如何使用AJAX更新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是產品belongs_to的地點, 個@locations位置的集合的每一個的has_many產品 因此使用了simple_form的關聯方法 位置也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

我不知道應該在局部視圖什麼代碼,上面的控制器應該呈現。

+0

如果您使用js事件觸發該查詢,是否可以在客戶端執行其餘的工作並完全避免異步調用?如果您不需要快速(或根本)堅持所有這些地點,一旦最終選擇完成,您是否可以這樣做? – jmargolisvt

+0

@jmargolisvt我曾考慮過,但是在客戶端做所有的事情,但它需要在視圖中加載更多的數據並編寫更多的代碼來處理這些值,這些值將複製模型中已存在的服務器端的功能,但是我終於找到了一種方法來做到這一點,我在下面的答案中解釋道。 –

回答

3

問題是我不知道如何更新simple_form中的一個元素。 我也有一個非常鬆散的使用AJAX的軌道不知道你可以同時具有HTML和JS部分視圖的同一個控制器,因爲我試圖讓我所有的代碼都只是HTML本來笨拙和反對不顯眼的JavaScript。

絆倒jQuery方法replaceWith也是非常有幫助的。

有了這些知識,我就能夠完成我所要做的事情。

我創建了一個JavaScript部分視圖,它響應AJAX調用而呈現。局部呈現一個.html.erb局部視圖,它用已更新的元素重建了一個simple_form。 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