Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby on Rails - drop down box on change event

I have two drop down boxes in my application. Based on the value selected in 1st combobox, the values in 2nd drop down box should be populated.And these values should come from Database.

Please help me.

like image 772
sanrda Avatar asked Jul 28 '11 18:07

sanrda


3 Answers

here's a clean approach using jquery-ujs (https://github.com/rails/jquery-ujs)

In your view:

<%= 
  select_tag  
      :first_select, # name of selectbox
      options_from_collection_for_select(@myrecords, "id", "name"), # your options for this select box
      :'data-remote' => 'true', # important for UJS
      :'data-url' => url_for(:controller => 'MyController', :action => 'getdata'), # we get the data from here!
      :'data-type' => 'json' # tell jQuery to parse the response as JSON!
%>


<%= 
   select_tag  
       :second_select, # name of selectbox
       "<option>Please select something from first select!</option>"
%> 

Your Controller:

class MyController < ApplicationController


  def getdata
    # this contains what has been selected in the first select box
    @data_from_select1 = params[:first_select]

    # we get the data for selectbox 2
    @data_for_select2 = MyModel.where(:some_id => @data_from_select1).all

    # render an array in JSON containing arrays like:
    # [[:id1, :name1], [:id2, :name2]]
    render :json => @data_for_select2.map{|c| [c.id, c.name]}
  end
end

In your application.js:

$(document).ready(function() {

  // #first_select is the id of our first select box, if the ajax request has been successful,
  // an ajax:success event is triggered.

  $('#first_select').live('ajax:success', function(evt, data, status, xhr) {
    // get second selectbox by its id
    var selectbox2 = $('#second_select');

    // empty it
    selectbox2.empty();

    // we got a JSON array in data, iterate through it

    $.each(data, function(index, value) {
      // append an option
      var opt = $('<option/>');

      // value is an array: [:id, :name]
      opt.attr('value', value[0]);
      // set text
      opt.text(value[1]);
      // append to select
      opt.appendTo(selectbox2);
    });
  });

});
like image 124
sled Avatar answered Nov 06 '22 16:11

sled


You could take inspiration from what I have in a project of mine. It updates the state given the country selected. It makes use of Carmen a great gem listing countries, states etc...

View:

<p>
  <label>Country <span>*</span></label>
  <%= profile_form.select(:country,Carmen.countries, {:include_blank => 'Select a Country'}, :id => "profile_country") %>
</p>
<p>
  <label>State <span>*</span></label>
  <%= profile_form.select(:state,  "" , {:include_blank => 'Select a Country first'}, :id => "profile_state") %>
</p>

Jquery code:

$('#profile_country').change(function() {
  if ($(this).val() == '')
    {
    $('#profile_state').html( $('<option>No state provided for your country</option>'));
    }
  else {
   $.ajax({
    type: "GET",
    url: "/remote/get_states/" + encodeURIComponent($(this).attr('value')),
    success: function(data){
       if (data.content == 'None')  //handle the case where no state related to country selected
         {
         $('#profile_state').empty();
         $('#profile_state').append( $('<option>No state provided for your country</option>'));
         }
        else
         {
         $('#profile_state').empty();
         $('#profile_state').append( $('<option>Select your State</option>'));
         jQuery.each(data,function(i, v) {
           $('#profile_state').append( $('<option value="'+ data[i][1] +'">'+data[i][0] +'</option>'));
         });
       }
     }
   });
 }
});

Controller:

def states
  begin
    render :json => Carmen::states(CGI::unescape(params[:country]))
  rescue 
    render :json => {"content" => "None"}.to_json
  end
end   
like image 32
apneadiving Avatar answered Nov 06 '22 18:11

apneadiving


This is how I did it. Works in Rails 3.2

View:

<%= select_tag :major_category_select_id, options_from_collection_for_select(@majorcategories, 'id', 'name'), :'data-remote' => 'true', :'data-url' => url_for(:controller => 'listings', :action => 'submit_major_category', format: 'js') %>

Controller method:

def submit_major_category
    @major_category = MajorCategory.find(params[:major_category_select_id])
    @minor_categories = @major_category.minor_categories

    respond_to do |format|
      # format.html { render partial: 'minor_categories_select' }
      format.js
    end
  end

Routes:

get "listings/submit_major_category"

Then create a submit_major_category.js.erb file that gets responded to.

like image 21
bcackerman Avatar answered Nov 06 '22 17:11

bcackerman