1

I have this coffeescript for dynamic select boxes to show only those models in models select box which relate to selected makes in makes select box. And I am gonna have multiple fields working with this function separately, so anonymous function wont work.

Coffeescripts looks like this

../assets/javascripts/diys.coffee

DynamicSelect = (makesSelect, modelsSelect) ->
  $(document).on 'change', makesSelect, (evt) ->
    $.ajax 'update_make_models',
      type: 'GET'
      dataType: 'script'
      data: {
        make_id: $("'makesSelect' option:selected").val()
      }
      error: (jqXHR, textStatus, errorThrown) ->
        console.log("AJAX Error: #{textStatus}")
      success: (data, textStatus, jqXHR) ->
        console.log("Dynamic make select OK!")

../views/diys/update_make_models.coffee

$(modelsSelect).empty()
    .append("<%= escape_javascript(render "make_models/make_model") %>")

And here's part of my form, which will repeat multiple times, only id's will change, which I will pass as arguments to "DynamicSelect" function. So where and what do I need to put to launch this function properly?

<div class="vehicle_field">
    <%= f.fields_for :attached_vehicles do |av| %>
    <p>Select make</p>
    <%= av.select :make, options_for_select(@makes.collect { |m| [m.make_name, m.id] }), { include_blank: "Select make" }, { id: 'makes_select1' } %><br>
    <p>Select model</p>
    <%= av.select :model, (render "make_models/make_model"), {prompt: "Select model"}, { id: 'models_select1' } %><br>
    <p>Select years</p>
    <%= av.select :start_year, (Time.now.year + 1).downto(Time.now.year - 100).to_a, prompt: "Year (from)" %>
    <%= av.select :end_year, (Time.now.year + 1).downto(Time.now.year - 100).to_a, prompt: "Year (to)" %><br>
    <% end %>
</div>

------------------------------------------------------------------------------------------------------------------------------------ Edit, trying to accomplish dynamic select boxes with data-remote attribute as Richard Peck suggested

In console it seems that I'm getting right "make_id" in parameters when selecting make in makes select box, but I can't find the way to pass it to controllers @models variable, am I doing anything right?

Form part for selecting attached vehicles from view

<div class="vehicle_field">
    <%= f.fields_for :attached_vehicles do |av| %>
    <p>Select make</p>
    <%= av.select :make, (@makes.collect { |m| [m.make_name, m.id] }), { include_blank: "Select make" }, { data: { remote: true, url: "update_make_models", name: "make", update: "#diy_attached_vehicles_attributes_0_model"} } %><br>
    <p>Select model</p>
    <%= av.collection_select :model, @models, (render "make_models/make_model"), {prompt: "Select model"} %><br>
    <p>Select years</p>
    <%= av.select :start_year, (Time.now.year + 1).downto(Time.now.year - 100).to_a, prompt: "Year (from)" %>
    <%= av.select :end_year, (Time.now.year + 1).downto(Time.now.year - 100).to_a, prompt: "Year (to)" %><br>
    <% end %>
</div>

_make_model.html.erb partial

<% @models.collect do |models| %>
    <option value="<%= models.id %>"><%= models.make_model_name %></option>
<% end %>

New action in diys_controller

def new
  @diy = Diy.new
  @step = @diy.steps.new
  @attached_vehicle = @diy.attached_vehicles.new
  @step.add_images_to_steps.new
  @makes = Make.all
  @models = MakeModel.where("make_id = ?", params[:make])
end

Also removed both coffeescripts and edited routes

get '/diys/update_make_models', to: 'diys#new', as: 'update_make_models'

And this is what I'm getting in console after selecting make

Started GET "/diys/update_make_models?diy%5Battached_vehicles_attributes%5D%5B0%5D%5Bmake%5D=12" for ::1 at 2016-02-17 20:03:21 +0200
Processing by DiysController#new as JS
  Parameters: {"diy"=>{"attached_vehicles_attributes"=>{"0"=>{"make"=>"12"}}}}
  Make Load (1.0ms)  SELECT "makes".* FROM "makes"
  MakeModel Load (1.0ms)  SELECT "make_models".* FROM "make_models" WHERE (make_id = NULL)
  Rendered make_models/_make_model.html.erb (3.0ms)
  Rendered diys/_form.html.erb (151.0ms)
  Rendered diys/new.html.erb within layouts/application (260.0ms)
Completed 200 OK in 451ms (Views: 446.4ms | ActiveRecord: 2.0ms | Solr: 0.0ms)

1 Answer 1

1

You can just bind .on to the element itself:

#app/assets/javascripts/application.coffee   
$(document).on "change", "select#makes_select1", (evt) ->
  $.ajax 'update_make_models',
    type: 'GET'
    dataType: 'script'
    data:
      make_id: $(this).find("option:selected").val()
    error: (jqXHR, textStatus, errorThrown) ->
        console.log "AJAX Error: #{textStatus}"
    success: (data, textStatus, jqXHR) ->
        console.log "Dynamic make select OK!"

Something cool you'll want to look at is the data-remote attribute for select boxes:

= f.collection_select :attribute, @collection, :id, :name, {}, { data: {remote: true, url: "update_make_models"} }

This passes the variable params[:object][:attribute] to the data-url, which you'll be able to mange in your controller to pull back the required data you want.

Using the above code will rid you of the need for the ajax definition in your JS.

Sign up to request clarification or add additional context in comments.

4 Comments

I had it this way before, when I had only one field for attached_vehicles, but now that I'm gonna have many of those, i will have to write this same code multiple times only changing elements id's, isn't there any other way?
You can actually do something pretty cool, let me update the answer
Yea, maybe thats the best way of doing it, tried to make it work now for couple of hours, but cant figure it out. In console it seems that I'm getting right make id in parameters when selecting make, but can't pass it for @models variable. Edited my question, would be nice if you could check what i'm doing wrong :)
You need to call params[:diy][:attached_vehicles_attributes][0][:make] in your controller

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.