Rails Kitchen

It's a place to write on stuff I learned recently.

Implement Dependent Select in Active Admin

| Comments

One of my prevois project, I needed to populate product catalogs in second select box depends on the product selected in first select box in active admin input form. I implemented this by refering one of the example by @abidsm in his github repo.

Implementation

First we need to add dependent_select.js file.
Now we need to add logic to catalogs_product.rb in admin folder.
catalogs_product.rb
1
2
3
4
5
6
7
8
9
ActiveAdmin.register CatalogsProduct do
  form do |f|
    f.inputs "Details" do
      f.input :product, :as => :select, :collection => Product.all.collect {|product| [product.name, product.id] }
      f.input :catalog, :as => :select, :input_html => {'data-option-dependent' => true, 'data-option-url' => '/products/:catalogs_product_product_id/catalogs', 'data-option-observed' => 'catalogs_product_product_id'}, :collection => (resource.product ? resource.product.category.catalogs.collect {|catalog| [catalog.attr_name, catalog.id]} : [])
    end
    f.actions
  end
end
Here ‘data-option-dependent’ => true will bind depentent select js to catalog input field.

‘data-option-observed’ => ‘catalogs_product_product_id’ specify that, the catalog field is depending on input in product field. catalogs_product_product_id is the id of the product field in this form.

Now we need to specify the json method which will populate catalogs data depends on the product is selected in parent input select.
‘data-option-url’ => ‘/products/:catalogs_product_product_id/catalogs’

Now we need to add index method with json output in catelogs controller.
catalogs_controller.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
class CatalogsController < ApplicationController
  respond_to :json

  def index
    if params[:product_id]
      product = Product.find_by_id(params[:product_id])
      @catalogs = product.category.catalogs
    else
      @catalogs = Catalog.all
    end
    render :json => @catalogs.collect {|catalog| {:id => catalog.id, :name => catalog.attr_name} }
  end
end
routes.rb
1
2
3
4
5
6
DependentSelect::Application.routes.draw do
  root :to => 'pages#main'
  resources :products do
    resources :catalogs
  end
end
That’s it now you can see catalog select box will be repopulated when we select a product in product select box. This can be implemented in any of formastic input forms.

Comments