Rails Select Drop Down for States?
Asked Answered
C

14

74

I was wondering if maybe there was some already built in function for rails so that it would create a select drop down list with all the U.S. states so I wouldn't have to enter it manually. I searched online but I was unable to find any. Any suggestions on what to do so I don't have to manually enter all the states?

Chalfant answered 19/6, 2011 at 1:31 Comment(0)
A
143

some helper file

def us_states
    [
      ['Alabama', 'AL'],
      ['Alaska', 'AK'],
      ['Arizona', 'AZ'],
      ['Arkansas', 'AR'],
      ['California', 'CA'],
      ['Colorado', 'CO'],
      ['Connecticut', 'CT'],
      ['Delaware', 'DE'],
      ['District of Columbia', 'DC'],
      ['Florida', 'FL'],
      ['Georgia', 'GA'],
      ['Hawaii', 'HI'],
      ['Idaho', 'ID'],
      ['Illinois', 'IL'],
      ['Indiana', 'IN'],
      ['Iowa', 'IA'],
      ['Kansas', 'KS'],
      ['Kentucky', 'KY'],
      ['Louisiana', 'LA'],
      ['Maine', 'ME'],
      ['Maryland', 'MD'],
      ['Massachusetts', 'MA'],
      ['Michigan', 'MI'],
      ['Minnesota', 'MN'],
      ['Mississippi', 'MS'],
      ['Missouri', 'MO'],
      ['Montana', 'MT'],
      ['Nebraska', 'NE'],
      ['Nevada', 'NV'],
      ['New Hampshire', 'NH'],
      ['New Jersey', 'NJ'],
      ['New Mexico', 'NM'],
      ['New York', 'NY'],
      ['North Carolina', 'NC'],
      ['North Dakota', 'ND'],
      ['Ohio', 'OH'],
      ['Oklahoma', 'OK'],
      ['Oregon', 'OR'],
      ['Pennsylvania', 'PA'],
      ['Puerto Rico', 'PR'],
      ['Rhode Island', 'RI'],
      ['South Carolina', 'SC'],
      ['South Dakota', 'SD'],
      ['Tennessee', 'TN'],
      ['Texas', 'TX'],
      ['Utah', 'UT'],
      ['Vermont', 'VT'],
      ['Virginia', 'VA'],
      ['Washington', 'WA'],
      ['West Virginia', 'WV'],
      ['Wisconsin', 'WI'],
      ['Wyoming', 'WY']
    ]
end

in some form

<%= select_tag :state, options_for_select(us_states) %>
Arillode answered 19/6, 2011 at 1:39 Comment(6)
NP. This kinda stuff is not going to be include in rails. It's not agnostic and including all countries, states, etc... is not railsy at all.Arillode
i got a little problem though. the states arent showing up in my file. any suggestions? im just getting an empty select drop down box. maybe i should make it a partial?Chalfant
<%= select_tag :state, options_for_select(us_states) %> Arillode
If inside a form_for: = f.select :state, options_for_select(us_states),{}, class: 'form-control'Ganof
This worked for me. Any suggestions on how to reverse this for the Show view? In the form they can select 'Arizona' and it records in the database as 'AZ'; but, in the show page it shows as 'AZ', not 'Arizona'.Sympathetic
undefined local variable or method `status'Mayemayeda
A
30

Thanks Codeglot. In case anyone is wanting to display the 2-letter state abbreviation instead of the full name:

def us_states
  [
    ['AK', 'AK'],
    ['AL', 'AL'],
    ['AR', 'AR'],
    ['AZ', 'AZ'],
    ['CA', 'CA'],
    ['CO', 'CO'],
    ['CT', 'CT'],
    ['DC', 'DC'],
    ['DE', 'DE'],
    ['FL', 'FL'],
    ['GA', 'GA'],
    ['HI', 'HI'],
    ['IA', 'IA'],
    ['ID', 'ID'],
    ['IL', 'IL'],
    ['IN', 'IN'],
    ['KS', 'KS'],
    ['KY', 'KY'],
    ['LA', 'LA'],
    ['MA', 'MA'],
    ['MD', 'MD'],
    ['ME', 'ME'],
    ['MI', 'MI'],
    ['MN', 'MN'],
    ['MO', 'MO'],
    ['MS', 'MS'],
    ['MT', 'MT'],
    ['NC', 'NC'],
    ['ND', 'ND'],
    ['NE', 'NE'],
    ['NH', 'NH'],
    ['NJ', 'NJ'],
    ['NM', 'NM'],
    ['NV', 'NV'],
    ['NY', 'NY'],
    ['OH', 'OH'],
    ['OK', 'OK'],
    ['OR', 'OR'],
    ['PA', 'PA'],
    ['RI', 'RI'],
    ['SC', 'SC'],
    ['SD', 'SD'],
    ['TN', 'TN'],
    ['TX', 'TX'],
    ['UT', 'UT'],
    ['VA', 'VA'],
    ['VT', 'VT'],
    ['WA', 'WA'],
    ['WI', 'WI'],
    ['WV', 'WV'],
    ['WY', 'WY']
  ]
end
Affair answered 14/8, 2012 at 16:22 Comment(0)
S
18

For this I typically use the Carmen and Carmen-Rails gems.

https://github.com/jim/carmen

https://github.com/jim/carmen-rails

Since my projects are still all on Ruby 1.8, I have to use the specific ruby-18 branch, so I have the following in my Gemfile:

gem 'carmen', :git => 'git://github.com/jim/carmen.git', :tag => 'ruby-18'
gem 'carmen-rails', :git => 'git://github.com/jim/carmen-rails.git'

Then, to create the select tag for all US states in a form where you're editing the :state_code field of an :address model object...

subregion_select(:address, :state_code, Carmen::Country.coded('US'))
Shady answered 19/12, 2012 at 19:4 Comment(0)
R
18

This is a more detailed walkthrough. I'm using Rails 4:

Under the helpers folder I created states_helper.rb

Inside states_helper.rb:

module StatesHelper

def us_states
  [
    ['Alabama', 'AL'],
    ['Alaska', 'AK'],
    ['Arizona', 'AZ'],
    ['Arkansas', 'AR'],
    ['California', 'CA'],
    ['Colorado', 'CO'],
    ['Connecticut', 'CT'],
    ['Delaware', 'DE'],
    ['District of Columbia', 'DC'],
    ['Florida', 'FL'],
    ['Georgia', 'GA'],
    ['Hawaii', 'HI'],
    ['Idaho', 'ID'],
    ['Illinois', 'IL'],
    ['Indiana', 'IN'],
    ['Iowa', 'IA'],
    ['Kansas', 'KS'],
    ['Kentucky', 'KY'],
    ['Louisiana', 'LA'],
    ['Maine', 'ME'],
    ['Maryland', 'MD'],
    ['Massachusetts', 'MA'],
    ['Michigan', 'MI'],
    ['Minnesota', 'MN'],
    ['Mississippi', 'MS'],
    ['Missouri', 'MO'],
    ['Montana', 'MT'],
    ['Nebraska', 'NE'],
    ['Nevada', 'NV'],
    ['New Hampshire', 'NH'],
    ['New Jersey', 'NJ'],
    ['New Mexico', 'NM'],
    ['New York', 'NY'],
    ['North Carolina', 'NC'],
    ['North Dakota', 'ND'],
    ['Ohio', 'OH'],
    ['Oklahoma', 'OK'],
    ['Oregon', 'OR'],
    ['Pennsylvania', 'PA'],
    ['Puerto Rico', 'PR'],
    ['Rhode Island', 'RI'],
    ['South Carolina', 'SC'],
    ['South Dakota', 'SD'],
    ['Tennessee', 'TN'],
    ['Texas', 'TX'],
    ['Utah', 'UT'],
    ['Vermont', 'VT'],
    ['Virginia', 'VA'],
    ['Washington', 'WA'],
    ['West Virginia', 'WV'],
    ['Wisconsin', 'WI'],
    ['Wyoming', 'WY']
  ]
end
end

Under config -> environments I put the following inside development.rb and production.rb

config.action_controller.include_all_helpers = true

Finally, inside my view I put (this is typed out in Slim HTML)

= form_for :order_submissions, url: order_url, html: { id: "order_form"} do |f|
fieldset
.form-group
  = f.select(:state, options_for_select(us_states, "CA"))

The "CA" pre-selects California in the dropdown menu on load.

NOTE: I did NOT use select_tag. Using it gave me an undefined method error for select_tag (select_tag is in the Ruby guides, how can it be undefined?) Using just select made it work.

Replace answered 25/3, 2014 at 16:20 Comment(0)
C
6

I found a problem with using a helper to contain the states. It works perfectly when creating a new record but if I want to edit an existing record I want the state in the database to be preselected in the dropdown box. I couldn't get that to work using the helper. But it does work if you create a simple states table. Here's what worked for me:

Create a states table for the select box options

Generate a State model file and database table that only has columns for state_code and state_name (or whatever you want to call them). rails g model State state_code:string:uniq state_name:string --no-timestamps --no-test-framework. This will generate a migration file in the db/migrate folder. If you don't want an id column you can edit it by inserting , id: false into the create_table block declaration.

# db/migrate/timestamp_create_states.rb
class CreateStates < ActiveRecord::Migration
  def change
    create_table :states, id: false do |t|
      t.string :state_code, null: false
      t.string :state_name
    end
    add_index :states, :state_code, unique: true
  end
end

And migrate the database rake db:migrate.

You can populate the table using the seed file. Make sure to delete or comment out any previously loaded data in the seed file so you don't add duplicates.

#db/seeds.rb
states = State.create!([
  { state_name: 'Alaska', state_code: 'AK' },
  { state_name: 'Alabama', state_code: 'AL' },
  { state_name: 'Arkansas', state_code: 'AR' },
  { state_name: 'Arizona', state_code: 'AZ' },
  { state_name: 'California', state_code: 'CA' },
  { state_name: 'Colorado', state_code: 'CO' },
  { state_name: 'Connecticut', state_code: 'CT' },
  { state_name: 'District of Columbia', state_code: 'DC' },
  { state_name: 'Delaware', state_code: 'DE' },
  { state_name: 'Florida', state_code: 'FL' },
  { state_name: 'Georgia', state_code: 'GA' },
  { state_name: 'Hawaii', state_code: 'HI' },
  { state_name: 'Iowa', state_code: 'IA' },
  { state_name: 'Idaho', state_code: 'ID' },
  { state_name: 'Illinois', state_code: 'IL' },
  { state_name: 'Indiana', state_code: 'IN' },
  { state_name: 'Kansas', state_code: 'KS' },
  { state_name: 'Kentucky', state_code: 'KY' },
  { state_name: 'Louisiana', state_code: 'LA' },
  { state_name: 'Massachusetts', state_code: 'MA' },
  { state_name: 'Maryland', state_code: 'MD' },
  { state_name: 'Maine', state_code: 'ME' },
  { state_name: 'Michigan', state_code: 'MI' },
  { state_name: 'Minnesota', state_code: 'MN' },
  { state_name: 'Missouri', state_code: 'MO' },
  { state_name: 'Mississippi', state_code: 'MS' },
  { state_name: 'Montana', state_code: 'MT' },
  { state_name: 'North Carolina', state_code: 'NC' },
  { state_name: 'North Dakota', state_code: 'ND' },
  { state_name: 'Nebraska', state_code: 'NE' },
  { state_name: 'New Hampshire', state_code: 'NH' },
  { state_name: 'New Jersey', state_code: 'NJ' },
  { state_name: 'New Mexico', state_code: 'NM' },
  { state_name: 'Nevada', state_code: 'NV' },
  { state_name: 'New York', state_code: 'NY' },
  { state_name: 'Ohio', state_code: 'OH' },
  { state_name: 'Oklahoma', state_code: 'OK' },
  { state_name: 'Oregon', state_code: 'OR' },
  { state_name: 'Pennsylvania', state_code: 'PA' },
  { state_name: 'Puerto Rico', state_code: 'PR' },
  { state_name: 'Rhode Island', state_code: 'RI' },
  { state_name: 'South Carolina', state_code: 'SC' },
  { state_name: 'South Dakota', state_code: 'SD' },
  { state_name: 'Tennessee', state_code: 'TN' },
  { state_name: 'Texas', state_code: 'TX' },
  { state_name: 'Utah', state_code: 'UT' },
  { state_name: 'Virginia', state_code: 'VA' },
  { state_name: 'Vermont', state_code: 'VT' },
  { state_name: 'Washington', state_code: 'WA' },
  { state_name: 'Wisconsin', state_code: 'WI' },
  { state_name: 'West Virginia', state_code: 'WV' },
  { state_name: 'Wyoming', state_code: 'WY' }
])

Then run the rake task to seed the db rake db:seed

In your form you can add this as your select box (I'm using state_code as the field name but you can make it just state or whatever you want):

<%= f.label :state_code, 'State', class: 'control-label' %>
<%= f.collection_select(:state_code, State.select(:state_name, :state_code),
   :state_code, :state_name, {selected: 'CA'}, {class: 'form-control'}) %>

The collection_select helper method format in a Rails form block is f.collection_select(method, collection, value_method, text_method, options = {}, html_options = {}). If you want state_code as both the text and value of the dropdown box then change the :state_name to :state_code in the first select argument and in the text_method (note the text and value orders are reversed). In the options I preselected 'CA', but only do that for a new form not edit (or it will override the value with CA each time). You can change that to a blank {include_blank: true} or add a prompt {prompt: 'Select State'} or just have it default to the selected or first value with an empty hash {}. If you want to make the field required you can add that to the html options {class: 'form-control', required: true}

Now in your form you can populate it from the states table and it will preselect the value when editing a record.

Crocodilian answered 27/10, 2015 at 1:10 Comment(4)
I find this answer best. I don't like the idea of hard-coding data into the code.Satrap
I think this is overkill – the states aren't very likely to change (recent political events notwithstanding), so hard-coding it is fine.Liberate
Agreed, hardcoding may be fine, but Steve had a point that he was trying to get the dropdown to pre-select the state. I am coding with Rails 5, and this is what I did. I setup an if statement before the dropdown box to check if the state was recorded or nil. If it was nil, I set a temp variable to a default state of my choosing. If it was recorded, I set the temp variable to that state. Then, I called the temp variable in the select like so: <%= f.select :state, options_for_select(us_states, @temp_state), id: :profile_state %> Now, to figure out how to display the full name of the state.Sympathetic
Here is the code that I used to set the temp variable: <% if profile.state.nil? @temp_state = 'Arizona' else @temp_state = profile.state end %> Indentation and new lines don't show up in these comments, sorry.Sympathetic
M
6

To get this to work with simple_form, I did this.

Added this to my user.rb model:

STATES = 
  [
    ['Alabama', 'AL'],
    ['Alaska', 'AK'],
    ['Arizona', 'AZ'],
    ['Arkansas', 'AR'],
    ['California', 'CA'],
    ['Colorado', 'CO'],
    ['Connecticut', 'CT'],
    ['Delaware', 'DE'],
    ['District of Columbia', 'DC'],
    ['Florida', 'FL'],
    ['Georgia', 'GA'],
    ['Hawaii', 'HI'],
    ['Idaho', 'ID'],
    ['Illinois', 'IL'],
    ['Indiana', 'IN'],
    ['Iowa', 'IA'],
    ['Kansas', 'KS'],
    ['Kentucky', 'KY'],
    ['Louisiana', 'LA'],
    ['Maine', 'ME'],
    ['Maryland', 'MD'],
    ['Massachusetts', 'MA'],
    ['Michigan', 'MI'],
    ['Minnesota', 'MN'],
    ['Mississippi', 'MS'],
    ['Missouri', 'MO'],
    ['Montana', 'MT'],
    ['Nebraska', 'NE'],
    ['Nevada', 'NV'],
    ['New Hampshire', 'NH'],
    ['New Jersey', 'NJ'],
    ['New Mexico', 'NM'],
    ['New York', 'NY'],
    ['North Carolina', 'NC'],
    ['North Dakota', 'ND'],
    ['Ohio', 'OH'],
    ['Oklahoma', 'OK'],
    ['Oregon', 'OR'],
    ['Pennsylvania', 'PA'],
    ['Puerto Rico', 'PR'],
    ['Rhode Island', 'RI'],
    ['South Carolina', 'SC'],
    ['South Dakota', 'SD'],
    ['Tennessee', 'TN'],
    ['Texas', 'TX'],
    ['Utah', 'UT'],
    ['Vermont', 'VT'],
    ['Virginia', 'VA'],
    ['Washington', 'WA'],
    ['West Virginia', 'WV'],
    ['Wisconsin', 'WI'],
    ['Wyoming', 'WY']
  ]

Made the simple_form in my view use that:

<%= simple_form_for(@user) do |f| %>    
    <%= f.input :state, as: :select, collection: User::STATES %>
    <%= f.button :submit %>
<% end %>
Miru answered 6/12, 2015 at 1:15 Comment(0)
F
4

In case this one doesn't work:

<%= select_tag :state, us_states%>

Try this :

 <%=select_tag 'State', options_for_select(us_states),:name=>"state",:id=>"state"%>
Footwork answered 28/3, 2013 at 10:42 Comment(1)
I am using Rails 3 and this is what I had to do in order for this method to work. Fantastic answer Sachin.Traditional
L
3

You have a gem that can help you: the countries gem which integrates with country_select, so you have a complete solution for states input.

Also if you want to reduce the gem dependency list you can just do:

 <%= f.select :country_code, ::ISO3166::Country.all_names_with_codes,{ include_blank: true } %>
Lechery answered 26/8, 2013 at 15:57 Comment(0)
A
2

Use a hash. I put mine in config/initializers/us_states.rb, but it works in a helper or just about anywhere else you prefer:

US_STATES = {
  'AL': 'Alabama',
  'AK': 'Alaska',
  'AZ': 'Arizona',
  'AR': 'Arkansas',
  'CA': 'California',
  'CO': 'Colorado',
  'CT': 'Connecticut',
  'DE': 'Delaware',
  'DC': 'District of Columbia',
  'FL': 'Florida',
  'GA': 'Georgia',
  'HI': 'Hawaii',
  'ID': 'Idaho',
  'IL': 'Illinois',
  'IN': 'Indiana',
  'IA': 'Iowa',
  'KS': 'Kansas',
  'KY': 'Kentucky',
  'LA': 'Louisiana',
  'ME': 'Maine',
  'MD': 'Maryland',
  'MA': 'Massachusetts',
  'MI': 'Michigan',
  'MN': 'Minnesota',
  'MS': 'Mississippi',
  'MO': 'Missouri',
  'MT': 'Montana',
  'NE': 'Nebraska',
  'NV': 'Nevada',
  'NH': 'New Hampshire',
  'NJ': 'New Jersey',
  'NM': 'New Mexico',
  'NY': 'New York',
  'NC': 'North Carolina',
  'ND': 'North Dakota',
  'OH': 'Ohio',
  'OK': 'Oklahoma',
  'OR': 'Oregon',
  'PA': 'Pennsylvania',
  'PR': 'Puerto Rico',
  'RI': 'Rhode Island',
  'SC': 'South Carolina',
  'SD': 'South Dakota',
  'TN': 'Tennessee',
  'TX': 'Texas',
  'UT': 'Utah',
  'VT': 'Vermont',
  'VA': 'Virginia',
  'WA': 'Washington',
  'WV': 'West Virginia',
  'WI': 'Wisconsin',
  'WY': 'Wyoming'
}

Then, in my form:

<%= form.select :state, US_STATES.invert.sort %>

Since the two-letter code is what's stored, if I want to display the name of the state, I just reference the two-letter key in the hash:

<%= US_STATES[state] %>

If you want to get really slick, initialize them in a locale file (e.g., config/locales/en.yml):

---
en:
  us_states:
    AL: Alabama
    AK: Alaska
    AZ: Arizona
    # etc.

And access them in your views with:

<%= t "us_states.#{state}" %>

ℹ️ This actually works better with country and language codes when you support multiple languages in your app.

Anthony answered 19/10, 2020 at 10:28 Comment(0)
O
1

Check this https://rubygems.org/gems/country_state_select

Country State Select is a library that provides an easy API to generate Country , State / Province and City dropdowns for use in forms.

When implemented correctly, a State / Province dropdown is filled with appropriate regions based upon what Country a user has selected .

For instance, if a user chooses "United States of America" for a Country dropdown, the State dropdown will be filled with the 50 appropriate states plus the District of Columbia also then user can list city according to state selection but currently cities are limited.

Orenorenburg answered 30/10, 2015 at 18:22 Comment(0)
B
0

I don't know if there is something built-in Rails to make a HTML select field filled with U.S.A. states.

But here you have a screencast which explains this: http://railscasts.com/episodes/88-dynamic-select-menus

I hope it will be useful.

Barbet answered 19/6, 2011 at 1:46 Comment(1)
Earlier versions of Rails came with select tag helpers having states and country lists, but as Codeglot points out, it wasn't suitably agnostic and was removed. It's as easy as copying his code :-). Also note that the railscast linked has been updated.Bogle
H
0

I have created a sample project with detailed instructions on how to create drop-downs in Rails 4.2.2 and Ruby 2.2.2 https://rubyplus.com/articles/2501

Hegel answered 22/6, 2015 at 8:55 Comment(0)
S
0

if you want to save state on full name

# frozen_string_literal: true

module StateHelper

  def us_states
    [
      ['Alabama'],
      ['Alaska'],
      ['Arizona'],
      ['Arkansas'],
      ['California'],
      ['Colorado'],
      ['Connecticut'],
      ['Delaware'],
      ['District of Columbia'],
      ['Florida'],
      ['Georgia'],
      ['Hawaii'],
      ['Idaho'],
      ['Illinois'],
      ['Indiana'],
      ['Iowa'],
      ['Kansas'],
      ['Kentucky'],
      ['Louisiana'],
      ['Maine'],
      ['Maryland'],
      ['Massachusetts'],
      ['Michigan'],
      ['Minnesota'],
      ['Mississippi'],
      ['Missouri'],
      ['Montana'],
      ['Nebraska'],
      ['Nevada'],
      ['New Hampshire'],
      ['New Jersey'],
      ['New Mexico'],
      ['New York'],
      ['North Carolina'],
      ['North Dakota'],
      ['Ohio'],
      ['Oklahoma'],
      ['Oregon'],
      ['Pennsylvania'],
      ['Puerto Rico'],
      ['Rhode Island'],
      ['South Carolina'],
      ['South Dakota'],
      ['Tennessee'],
      ['Texas'],
      ['Utah'],
      ['Vermont'],
      ['Virginia'],
      ['Washington'],
      ['West Virginia'],
      ['Wisconsin'],
      ['Wyoming']
    ]
  end
end

And then in form

<%= f.select :state, options_for_select(us_states), class:"form-control", required: true %>

Skiles answered 6/12, 2019 at 19:54 Comment(0)
P
0

You don't need to create a method for this if you are using the Country gem

Country["US"].states.values.map(&:name)

This also works for other countries

Pageboy answered 1/3 at 14:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.