#977 new
Jon Crawford

[PATCH] Added grouped_options_for_select helper to form_options_helper for wrapping option tags in optgroups.

Reported by Jon Crawford | September 5th, 2008 @ 04:28 PM | in 2.x

Returns a string of <option> tags, using options_for_select, but wraps them with <optgroup> tags.


#Sample usage:
labels = ['North America','Europe']
groups = [['United States','Canada'], ['Denmark','Germany','France']]
optgroups_with_options_for_select(labels,groups)

#Possible output:
<optgroup label="North America">
  <option value="United States">United States</option>
  <option value="Canada">Canada</option>
</optgroup>
<optgroup label="Europe">
  <option value="Denmark">Denmark</option>
  <option value="Germany">Germany</option>
  <option value="France">France</option>
</optgroup>

Comments and changes to this ticket

  • Mislav

    Mislav September 5th, 2008 @ 09:33 PM

    +1

    I would like to see better naming:

    
    groups = ['North America','Europe']
    options = [, ]
    grouped_options_for_select(groups, options)
    
    # "option_groups_for_select" is also a good method name
    

    And how about this:

    
    grouped_options_for_select(
      'North America' => ['United States','Canada'],
      'Europe' => ['Denmark','Germany','France']
    )
    # => iterates over keys in alphabetical order ("Europe" would come first)
    
  • Mislav

    Mislav September 5th, 2008 @ 09:34 PM

    I ruined the 2nd line of my example by using cut instead of copy :/

  • Scott Raymond
  • Jon Crawford

    Jon Crawford September 5th, 2008 @ 10:22 PM

    I replied to some of Mislav's thoughts in the IRC channel but I'll repeat here.

    I avoided the options argument name because it is often used in many other helpers to mean an option set of arguments that may be passed. And I used the labels argument name because of the attribute in <optgroup label="Europe''>. I could easily budge on the labels one, but I personally think the options should be avoided. Note: options_for_select uses container.

    And to your point about using a hash and iterating in alphabetical order: In my very first implementation of this helper, I needed the groups in a specific order ("Mens, Womens, Children, Other"). Using alphabetical sorting means you lose a good deal of control (although it's much cleaner on first blush).

  • Yaroslav Markin
  • Eloy Duran
  • Mislav

    Mislav September 8th, 2008 @ 01:08 AM

    Jon,

    Re: hash argument and alphabetical order---I've only suggested that this could be an alternative to passing 2 arrays. Array arguments should be used when the user is in need of custom ordering.

  • Tom Lea

    Tom Lea September 8th, 2008 @ 09:55 AM

    The two arrays required to be equal length is a bit of a no no for me, how about accepting:

    
    labels = ['North America',]
    groups = [
      ['North America',
        ['United States','Canada']],
      ['Europe',
        ['Denmark','Germany','France']]
    ]
    
    grouped_options_for_select(labels,groups)
    

    This accepts things in order and will keep them in order, ala Jon's requirements.

    Code designed for this should be able to handle a hash too ([[:a, :b]].each{|c| break c} == {:a => :b}.each{|c| break c}), as per Mislav's ideas.

    This also avoids the slightly icky Error: Sizes don't match, as this is now an impossible state to reach.

    There is no basic issue with the idea, it's good, but needs some more work on the method signature, just does not feel railsy enough.

    Any chance of an updated patch Jon?

  • Tom Lea

    Tom Lea September 8th, 2008 @ 09:57 AM

    1's example is wrong... should be

    
    grouped_options = [
      ['North America',
        ['United States','Canada']],
      ['Europe',
        ['Denmark','Germany','France']]
    ]
    
    grouped_options_for_select(grouped_options)
    
  • Jon Crawford

    Jon Crawford September 8th, 2008 @ 05:13 PM

    Tom-

    I made the changes you suggested. I never liked that error at the beginning, but I didn't want to raise an exception either. Maybe I'm too nice? :-D

    It now accepts either a nested Array or a Hash.

    I also changed the helper name to grouped_options_for_select.

    Let me know if you guys have any other suggestions.

  • Jon Crawford

    Jon Crawford September 9th, 2008 @ 01:52 AM

    • → Title changed from “[PATCH] Added optgroups_with_options_for_select helper to form_options_helper for wrapping option tags in optgroups.” to “[PATCH] Added grouped_options_for_select helper to form_options_helper for wrapping option tags in optgroups.”

    Further updated patch including better testing and improved documentation.

  • grosser

    grosser September 17th, 2008 @ 12:11 PM

    • → Tag changed from “actionpack enhancement helper patch tested” to “actionpack enhancement helper patch tested”

    What i am using atm:

    continents = [['Africa',['Norway','NO']]] select_tag('country',option_groups_for_select(continents,'NO'))

    #continentes = [['Africa',['NA','Namibia'],['XX']...],...] def option_groups_for_select(collection,selected = nil)

    collection.inject('') do |options_for_select,group|
      group_label_string = group[0]
      options_for_select = "<optgroup label=\"#{html_escape(group_label_string)}\">"
      options_for_select += options_for_select(group[1..-1],selected)
      options_for_select += '</optgroup>'
    end
    
    

    end

  • grosser

    grosser September 17th, 2008 @ 12:12 PM

    once again(weird formattting)...

    #continentes = [['Africa',['NA','Namibia'],['XX']...],...]
    def option_groups_for_select(collection,selected = nil)
      collection.inject('') do |options_for_select,group|
        group_label_string = group[0]
        options_for_select = "<optgroup label=\"#{html_escape(group_label_string)}\">"
        options_for_select += options_for_select(group[1..-1],selected)
        options_for_select += '</optgroup>'
      end
    end
    
    
  • Sean Cribbs
  • grosser.michael+lighthouse (at gmail)

    grosser.michael+lighthouse (at gmail) October 4th, 2008 @ 08:02 AM

    There was a small errror in my above post:

    options_for_select = "<optgroup label=\"#{html_escape(group_label_string)}\">"
    
    

    should be

    options_for_select += "<optgroup label=\"#{html_escape(group_label_string)}\">"
    
    

Please Login or create a free account to add a new comment.

You can update this ticket by sending an email to from your email client. (help)

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

Source available from github

The Git repository resides at http://github.com/rails

Check out the current development trunk (Edge Rails) with:

git clone git://github.com/rails/rails.git

Creating or reviewing a patch

See the contributor guide.

Creating a feature request

Please don't. If you want a new feature in Rails, you'll have to pull up your sleeves and get busy yourself. Or convince someone else to do it. See the contributor guide on how to get going. But posting them here is just going to lead to ticket root.

Creating a bug report

When creating a bug report, be sure to include as much relevant information as possible. Post the code sample that causes the problem. Preferably, alter the unit tests and show through either changed or added tests how the expected behavior is not occuring.

Security vulnerabilities should be reported via an email to security@rubyonrails.org, do not use trac for reporting security vulnerabilities. All content in trac is publicly available as soon as it is posted.

Then don't get your hopes up. Unless you have a "Code Red, Mission Critical, The World is Coming to an End" kinda bug, you're creating this ticket in the hope that others with the same problem will be able to collaborate with you on solving it. Do not expect that the ticket automatically will see any activity or that others will jump to fix it. Creating a ticket like this is mostly to help yourself start on the path of fixing the problem and for others to sign on to with a "I'm having this problem too".

Shared Ticket Bins