Skip to content

ChakreshwarSharma/us_zipcode

Repository files navigation

Us Zip Code

Simple gem to handle zipcode lookups and related functionality. rake zipcodes:update will automatically download and update your local zipcode database. Generates three models for extended zipcode functionality.

Installation

Add the following line to your Gemfile:

gem 'us_zipcode'

Run:

bundle install

Generate the models and populate the data:

rails g us_zipcode:models
rake db:migrate
rake zipcodes:update

You should now have three new tables and three new models, Zipcode, State, County.

Usage

zipcode = Zipcode.find_by_code '66206'
zipcode.state.abbr    # => 'KS'
zipcode.city          # => 'Shawnee Mission'
zipcode.county.name   # => 'Johnson'
zipcode.lat.to_s      # => '38.959356', it is actually a BigDecimal object converted to_s for documentation.
zipcode.lon.to_s      # => '-94.716155', ditto
zipcode.is_geocoded?  # => true, most if not all should be pre-geocoded.

You can use State and County objects as follows:

state = State.find_by_abbr "MO"
state.cities.count    # => 963
state.cities          # gives you a sorted array of all cities for the state
state.zipcodes.count  # => 1195
...
county = state.counties.first
county.cities.count   # => 5
county.cities         # gives you a sorted array of all cities for the county
county.zipcodes.count # => 5

Look Up City by State & zip code + county by city

First you have to select a state .On state selection , you can see the cities drop down which are associated with the selected state.
On city selection, you can see the corresponding county with its zip code.

Write the following code in your view:

<%= select_tag "state",options_from_collection_for_select(State.all, "id", "name") %>
<div id ="city"></div>
<div id ="county"></div>
<script>
  $("#state").on("change", function () {
    $.ajax({
      url: "/mycontroller/get_cities_by_state",
      dataType: "script",
      method: "get",
      data: {state_id: $(this).val()}
    });
    $("#county").html('');
  });
</script> 

Create mycontroller & paste the following code:

def get_cities_by_state
    @cities = Zipcode.group(:city).where(state_id: params[:state_id])
  end
 def get_county_and_zip_by_city    
    @zipcodes = Zipcode.find_by_city(params[:city])
  end

Create the following two js.erb files in app/views/mycontroller/

1.get_cities_by_state.js.erb & paste the following code:

$("#city").html('<%= escape_javascript(select_tag "city", options_from_collection_for_select(@cities, :id, :city)) %>');
$("#city").on("change", function(){
  $.ajax({
    url: "/mycontroller/get_county_and_zip_by_city",
    dataType: "script",
    method: "get",
    data: {city: $("#city select option:selected"). text()}
  });
});

2.get_county_and_zip_by_city.js.erb

$("#county").html('<%= escape_javascript(select_tag "county", options_from_collection_for_select(@zipcodes, :id, :county_and_zip)) %>');

In the last update your routes:

scope '/mycontroller' do
     get 'get_cities_by_state' => 'mycontroller#get_cities_by_state'
     get 'get_county_and_zip_by_city' => 'mycontroller#get_county_and_zip_by_city'
    end

Automatic JQuery/AJAX lookup

You can have a user enter a zipcode and automatically lookup their city, state and county.

Put something like this in your view:

f.text_field :zip, :size => 5, :maxlength => 5, :class => 'zipcode_interactive'
f.text_field :city, :size => 20, :maxlength => 60, :readonly => true
f.text_field(:state, :size => 2, :maxlength => 2, :readonly => true)
f.text_field(:county, :size => 20, :maxlength => 60, :readonly => true)

Then add this to your application.js, but remember to replace [mycontrollername] with your own controller.

   $(document).ready(function() {
        // Interactive Zipcodes
        $('input.zipcode_interactive').blur(function(data) {
            var elem_id = $(this).attr("id");
            var base_id = elem_id.substring(0, elem_id.lastIndexOf("_"));
            $.get("/mycontrollername/get_zip_data/" + this.value, {},
            function(data) {
                var zipcode = $.parseJSON(data);
                var city = $('#' + base_id + '_city');
                var state = $('#' + base_id + '_state');
                var county = $('#' + base_id + '_county');
                if (zipcode.err) {
                    alert(zipcode.err);
                } else {
                    city.val(zipcode.city);
                    state.val(zipcode.state)
                    county.val(zipcode.county)
                }
            })
        });
    });

You will also need a controller method similar to this, which will return the data to your form:

   def get_zip_data
      @zipcode = Zipcode.find_by_code(params[:code], :include => [:county, :state])
      if @zipcode
        @counties = County.find(:all, :conditions => [ "state_id = ?", @zipcode.county.state_id ])
        data = {
          'state' => @zipcode.state.abbr,
          'county' => @zipcode.county.name,
          'city' => @zipcode.city.titleize
        }
        render :text => data.to_json
      else
        if params[:code].blank?
          return true
        else
          if params[:code].is_zipcode?
            data = {
              'err' => "Could not find Zipcode [#{params[:code]}].  If this is a valid zipcode please notify support <support@mydomain.com>, so we can update our database."
            }
          else
            data = {
              'err' => "[#{params[:code]}] is not a valid Zipcode."
            }
          end
          render :text => data.to_json
        end
      end
    end

And define a route for the AJAX function in routes.rb:

get 'mycontrollername/get_zip_data/:code', :controller => 'mycontrollername', :action => 'get_zip_data'

That’s about it.

Let me know if there are any errors. I cut and pasted the code above from a working application, but there may be some gotchas that I missed.

About

US state list with city, county & zip

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published