How do I properly create a menu with optgroup labels?


I'm trying to produce a select menu with "optgroup" tags. The HTML output should look like this:

<optgroup label="Europe"> <option value="Denmark">Denmark</option> <option value="Germany">Germany</option> <option value="France">France</option> </optgroup> <optgroup label="North America"> <option value="US">United States</option> <option value="Canada">Canada</option> </optgroup>

In rails I'm typing this:

<%= :member_1, grouped_options_for_select ([['North America',[['United States','US'],'Canada']], ['Europe',['Denmark','Germany','France']]]) %>

select is not expecting a chunk of html, it's expecting something like [['option label', option_value], ...]

you might want to use either select_tag (which is expecting a blob of html)


You need to specify the right name for select_tag. Easiest way to do that is to switch back to, look at the html and use the name it generated for the select tag.


Thanks for that. I have now changed the code thus:

<%= select_tag "applicant[member_1]", grouped_options_for_select(@grouped_options) %>

and now I can pick up :member_1 in the params. Hooray.

One last thing though, when I submit the form the select menu always springs back to its initial value (in this case "United States"), regardless of what was previously selected.

Is there any way to alter this? I tried using :selected => "Canada" for example, but that didn't work.

Thanks very much for your help so far.

you need to tell grouped_options_for_select what the value of the selected option is


you need to tell grouped_options_for_select what the value of the selected option is


Wonderful. I checked the documenttation for grouped_options_for_select again, and you are completely right. It's done with the use of selected_key.

The code now reads: <%= select_tag "applicant[member_3]", grouped_options_for_select(@grouped_options, selected_key = "Canada") %>

And works perfectly.

Thanks very much for your help.

P.S. Hopefully I can now give all of the options an ID and pass this back in from the controller so it would read "selected_key = @sel_key"

In case this helps anyone else, I now have:


def index @members_group = [ ["Molecular Neuroscience", [["Prof. Dr. Denise Manahan-Vaughan", "1"], ["Prof. Dr. Lutz Pott", "2"]]], ["Developmental Neuroscience", [["Prof. Dr. Petra Wahle", "3"], ["Prof. Dr. Andreas Faissner", "4"], ["Dr. Alexander von Holst", "5"]]], ["Systems Neuroscience", [["Prof. Dr. Dr. Hanns Hatt", "6"], ["Prof. Dr. Klemens Stoertkuhl", "7"]]], ["Cognitive Neuroscience", [["Prof. Dr. Dr. h.c. Onur Guentuerkuen", "8"], ["Prof. Dr. Irene Daum", "9"], ["Prof. Dr. Oliver T. Wolf", "10"]]], ["Clinical Neuroscience", [["Prof. Dr. Martin Tegenthoff", "11"]]], ["Computational Neuroscience", [["Prof. Dr. Gregor Schoener", "12"], ["Jun. Prof. Dr. Christian Igel", "13"], ["Dr. Rolf Wuertz", "14"]]], ]

@applicant =[:applicant]) if( and   @name = "public/pdfs/#{@applicant.last_name}.pdf"   redirect_to :action => "success" else   @member_1 = @applicant.member_1   render :action=> "index" end end

In form.html.erb: ... <%= select_tag "applicant[member_1]", grouped_options_for_select(@members_group, selected_key = @member_1, prompt = " ") %>

This works perfectly.

Harpal Gujral wrote:

This post was really helpful in understanding the problem but how do we pass in the selected key if we're dealing with multiple nested attributes:

<select class="item" id="invoice_invoice_line_items_attributes_0_item" name="invoice[invoice_line_items_attributes][0][item]" ...>

<select class="item" id="invoice_invoice_line_items_attributes_1_item" name="invoice[invoice_line_items_attributes][1][item]" ...>


I need help filling in the blanks for this piece of code: grouped_options_for_select (@items, @invoice.invoice_line_items[???].item, "Please select...")

How do I pick up the current index value so that I can set the right selected key?

I had the same problem with nested attributes. You can use builder.object to access the current object for this form. I ended up using something like this to get it to work:

<% f.fields_for :invoice_line_items do |builder| %> <%= select_tag builder.object_name+'[item]',       grouped_options_for_select(         @items,         builder.object.item,         "Please select..."       ) %>

I'm sure there is a more elegant solution involving a monkey-patch of ActionView::Helpers::FormBuilder but I haven't gotten that far yet.