How do I properly create a menu with optgroup labels?


#1

Hi,

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

Denmark Germany France United States Canada

In rails I’m typing this:

<%= f.select :member_1,
grouped_options_for_select ([[‘North America’,[[‘United
States’,‘US’],‘Canada’]],
[‘Europe’,[‘Denmark’,‘Germany’,‘France’]]]) %>

The result is that rails is adding the generated HTML to the select
menu, that is to say that in the generated menu, instead of seeing:

Europe
Denmark
France

etc …

I see

Denmark

etc…

(See attachment)

Here is the HTML produced by Rails:

<optgroup label="North America">< option value="US">United States</option> ....

Can anyone help me to sort this out?
What am I doing wrong?
How do I properly create a menu with optgroup labels?

Thanks in advance for your help


#2

On Apr 27, 10:52 am, Jim B. removed_email_address@domain.invalid
wrote:

United States Canada

In rails I’m typing this:

<%= f.select :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)

Fred


#3

Hi Fred,
Well that worked :slight_smile:
I changed
<%= f.select :member_1
into
<%= select_tag :member_1
and got 100% the desired result.

Only problem is, is that I am using
<% form_for :applicant, :url=> {:action => “index”} do |f| %>
to create my form and removing the reference to the applicant object
(“f”), means that the value for “member_1” does not get passed when I
submit the form.

Is there any way around this?
sort of “f.select_tag” (which obviously doesn’t work)


#4

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.


#5

On Apr 27, 12:17 pm, Jim B. removed_email_address@domain.invalid
wrote:

to create my form and removing the reference to the applicant object
(“f”), means that the value for “member_1” does not get passed when I
submit the form.

Is there any way around this?

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

Fred


#6

On Apr 27, 2:28 pm, Jim B. removed_email_address@domain.invalid
wrote:

springs back to its initial value (in this case “United States”),
regardless of what was previously selected.

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

Fred


#7

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

Fred

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


#8

In case this helps anyone else, I now have:

form_controller.rb:

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.new(params[:applicant])
if(request.post? and @applicant.save)
@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.


#9

Jim B. wrote:

In case this helps anyone else, I now have:

form_controller.rb:

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.new(params[:applicant])
if(request.post? and @applicant.save)
@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.

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]” …>

etc.

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?


#10

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]” …>

etc.

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.