0

I'm trying to build a RoR app, with three models:

  • Games that can be classified in a Sector(called GameSector) and in a subsector (called GameSubsector)
  • A sector is made up of many subsectors.
  • a Subsector.

Here are my basic models relationships:

models/game.rb

belongs_to :game_sector,    :foreign_key => 'game_sector_id',   :counter_cache => true
belongs_to :game_subsector, :foreign_key => 'game_subsector_id',:counter_cache => true

I use Active Admin to input the Games, Sectors or subsectors information.

I have a very basic form when I create a game and I'd just like to make the second select drop down (game_subsector) adjust on the choice of the first select (gamesector) so that I don't the the whole (very long) list of game_subsectors but only those that belong to the game_sector I choose.

After dozens of tests and techniques tried but failing, I've finally used this dev's advice that appeared relevant to me: http://samuelmullen.com/2011/02/dynamic-dropdowns-with-rails-jquery-and-ajax/.

But it still does not work.

Here is the form on Active Admin which is located on admin/game.rb

ActiveAdmin.register Game do

  menu :parent => "Campaigns", :priority => 1

  controller do 
    with_role :admin_user      

      def game_subsectors_by_game_sector
      if params[:id].present?
        @game_subsectors = GameSector.find(params[:id]).game_subsectors
      else
        @game_subsectors = []
      end

      respond_to do |format|
        format.js
      end
    end

  end


form do |f|

    f.inputs "Details" do
      f.input :name
      f.input :game_sector_id,
        :label => "Select industry:",
        :as => :select, :collection => GameSector.all(:order => :name),
        :input_html => { :rel => "/game_sectors/game_subsectors_by_game_sector" }
      f.input :game_subsector_id, :as => :select, :collection => GameSubsector.all(:order => :name)

f.actions
  end

I feel the javascript is even maybe not fired.

The jquery I use is located on app/assets/javascript/admin/active_admin.js (I changed config so it loads this javascript when loading active admin pages)

jQuery.ajaxSetup({
  'beforeSend': function(xhr) { xhr.setRequestHeader("Accept", "text/javascript"); }
});

$.fn.subSelectWithAjax = function() {
  var that = this;

  this.change(function() {
    $.post(that.attr('rel'), {id: that.val()}, null, "script");
  });
};

$("#game_game_sector_id").subSelectWithAjax(); //it it found in my view???

Finally I created a view as this expert adviced: in app/views/layout/ game_subsectors_by_game_sector.js.erb

$("#game_game_subsector_id").html('<%= options_for_select(@game_subsectors.map {|sc| [sc.name, sc.id]}).gsub(/n/, '') %>');

I'm not sure I have out it in the right place though...

user229044
  • 232,980
  • 40
  • 330
  • 338
Mathieu
  • 4,587
  • 11
  • 57
  • 112

1 Answers1

2

What you need is:

  1. Inspect with your web browser console your selects, and use a CSS selector to create a jQuery object for the sector select, something like:

    $('#sector_select')
    
  2. Append to this object a handler, so when it changes AJAX request is fired:

    $('#sector_select').change(function(){
      $.ajax('/subsectors/for_select', {sector_id: $(this).val()})
        .done(function(response){ // 3. populate subsector select
          $('#subsector_select').html(response);
        });
    });
    
  3. See 3 in code, you need to inspect to get the right CSS selector. Be sure you are getting the expected response in the Network tab of your web browser inspector(if using Chrome).

  4. You need a controller that answers in /subsectors/for_select, in the file app/controllers/subsectors_controller.rb:

    class SubsectorsController  < ApplicationController
      def for_select
        @subsectors = Subsector.where sector_id: params[:sector_id]
      end
    end
    
  5. You need a view that returns the options to be populated app/views/subsectors/for_select.html.erb:

    <% @subsectors.each do |ss| %>
      <option value="<%= ss.id %>"><%= ss.name %></option>
    <% end %>
    
  6. You need a route:

    get '/subsectors/for_select', to: 'subsectors#for_select'
    
sites
  • 21,417
  • 17
  • 87
  • 146