Advanced Ext JS Form Controls with Ruby on Rails: ComboBox

The Ext Scaffold Generator Plugin for Ruby on Rails provides a quick start for single-model forms. When proceeding from the generated code to an actual application, one question keeps popping up in no time:

"How can I have a ComboBox in my form populated with choices from some other model to assign a association?"

Say, you have a Post model for blog posts and a Category model, similiar to the one we used in the Treeview example. Each Post belongs to a Category:

class Post < ActiveRecord::Base
  belongs_to :category
  # has attributes: id, title, body, category_id
end

class Category < ActiveRecord::Base
  # has attributes: id, name
end

If we were using just Rails without Ext JS, we would probably have the select form helper build a HTML select field ending up with this sort of code in our view:

<%= select :post, :category_id,
       Category.find(:all).collect {|c| [ c.name, c.id ] },
       { :include_blank => true } %>

Guess what? You can use the exact same code with Ext JS. One of the handy features of Ext.form.ComboBox is the ability to transform an existing HTML select tag into one of Ext's nice looking controls.

To turn above select field into a Ext.form.ComboBox we can use this form item configuration:

{ fieldLabel:    'Category',
  xtype:         'combo',
  triggerAction: 'all',
  typeAhead:      true,
  forceSelection: true,
  transform:     'post_category_id',
  lazyRender:     true
}

A complete _form_items.html.erb partial (as used with the Ext Scaffold Generator) would then look like this:

<%= select :post, :category_id,
       Category.find(:all).collect {|c| [ c.name, c.id ] },
       { :include_blank => true } %>
<% javascript_tag do -%>
  var <%= "#{form_items}" %> = [
    <%= ext_field(:field_label => 'Title', :name => 'post[title]', :xtype => :text_field) %>,
    <%= ext_field(:field_label => 'Body',  :name => 'post[body]',  :xtype => :text_area) %>,
    { fieldLabel:    'Category',
      xtype:         'combo',
      triggerAction: 'all',
      typeAhead:      true,
      forceSelection: true,
      transform:     'post_category_id',
      lazyRender:     true
    }
  ];
<% end -%>

Recommend Martin Rehfeld on Working With RailsIf this mini-tutorial was useful to you, please consider recommending me on Working with Rails. Thank you!

Related Posts