I have been trying for a while to implement a dynamic dependent form using AJAX in rails 4.0. I have a bike
model which has_one
make
and model
. It also has_many
quotes
. The goal is to have the second form's collection field ( model
) populate after the first field make
is selected.
The form loads correctly and the AJAX call once the first field is selected is made and returns the appropriate set of data (confirmed via puts in the console). However, I am unable to figure out how to then render the partial appropriately. I am getting the error below. I understand there is no f variable once the partial is rendered via the AJAX call but how do I go about designing the form without the f variable?
ActionView::Template::Error (undefined local variable or method `f' for #<#<Class:0x007f95b0fc2068>:0x007f95b54e2490>):
1: <%= f.label :name, 'Model' %>
2: <% if !current_models.blank? %>
3: <%= f.collection_select :name, current_models.collect{ |m| [m.name,m.id]}, :id , :name, include_blank: true %>
4: <% else %>
app/views/shared/_model_questions_fields.html.erb:1:in `_app_views_shared__model_questions_fields_html_erb__894239665582553972_70140482609500'
app/controllers/quotes_controller.rb:70:in `update_model_select'
quotes/new.html.erb
<%= form_for @quote do |f| %>
<%= f.fields_for :bikes do |builder| %>
<p><%= render 'shared/bike_questions_fields', :f => builder %></p>
<% end %>
<%= f.submit "Show Quote", class: "btn btn-large btn-primary" %>
<% end %>
'shared/bike_questions_fields'
<%= f.fields_for :makes do |builder| %>
<p><%= render 'shared/make_questions_fields', :f => builder %></p>
<% end %>
<%= f.fields_for :models do |builder| %>
<div id="bikeModels"
<p><%= render 'shared/model_questions_fields', :f => builder, :current_models => [] %></p>
</div>
<% end %>
'shared/model_questions_fields'
<%= f.label :name, 'Model' %>
<% if !current_models.blank? %>
<%= f.collection_select :name, current_models.collect{ |m| [m.name,m.id]}, :id , :name, include_blank: true %>
<% else %>
<%= f.collection_select :name, [], :id , :name, include_blank: true %>
<% end %>
in quotes controller:
def update_model_select
models = Model.where(:make_id=>params[:id]).order(:name) unless params[:id].blank?
render :partial => "shared/model_questions_fields", :locals => { :current_models => models }
end
in quotes.js.coffee:
ready = ->
jQuery ($) ->
# when the #make field changes
$("#quote_bikes_makes_name").change ->
# make a POST call and replace the content
make = $("select#quote_bikes_makes_name :selected").val()
make = "0" if make is ""
jQuery.get "/quotes/update_model_select/" + make, (data) ->
$("#bikeModels").html data
false
$(document).ready(ready)
$(document).on('page:load', ready)
I solved this by changing 'shared/model_questions_fields'
to:
<%= form_for('quote', remote: true) do |f| %>
<%= f.fields_for :bikes do |g| %>
<%= g.fields_for :models do |i| %>
<%= i.label :name, 'Model' %>
<% if !current_models.blank? %>
<%= i.collection_select :name, current_models, :id , :name, include_blank: true %>
<% else %>
<%= i.collection_select :name, [], :id , :name, include_blank: true %>
<% end %>
<% end %>
<% end %>
<% end %>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.