From ef3b2a0e0680090cb4e3c1131b3bed76cfaea37f Mon Sep 17 00:00:00 2001 From: Arvind Vyas Date: Sun, 25 Oct 2015 01:16:57 +0530 Subject: [PATCH] Added city select in to the country state select :) --- .../country_state_select/cscs_controller.rb | 9 +++ config/routes.rb | 7 +- lib/country_state_select.rb | 7 +- spec/country_state_select_spec.rb | 24 +++++- .../app/assets/javascripts/locations.coffee | 2 +- test/dummy/app/form/location_form.rb | 1 + test/dummy/app/views/locations/_form.html.erb | 2 + ...151024160724_add_test_city_to_locations.rb | 5 ++ test/dummy/db/schema.rb | 3 +- .../javascript/country_state_select.js.erb | 81 ++++++++++++++++++- 10 files changed, 132 insertions(+), 9 deletions(-) create mode 100644 test/dummy/db/migrate/20151024160724_add_test_city_to_locations.rb diff --git a/app/controllers/country_state_select/cscs_controller.rb b/app/controllers/country_state_select/cscs_controller.rb index 64157df..52a99ae 100644 --- a/app/controllers/country_state_select/cscs_controller.rb +++ b/app/controllers/country_state_select/cscs_controller.rb @@ -8,5 +8,14 @@ def find_states format.json { render :json => csc.to_a} end end + + # Sent it to state_id and country id it will return cities of that states + def find_cities + cities = CS.cities(params[:state_id].to_sym, params[:country_id].to_sym) + + respond_to do |format| + format.json { render :json => cities.to_a} + end + end end end \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 31edc57..0bc8e24 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,5 +1,6 @@ Rails.application.routes.draw do - scope :module => "country_state_select" do - post 'find_states' => 'cscs#find_states' - end + scope :module => "country_state_select" do + post 'find_states' => 'cscs#find_states' + post 'find_cities' => 'cscs#find_cities' + end end \ No newline at end of file diff --git a/lib/country_state_select.rb b/lib/country_state_select.rb index 78bc060..c40acb3 100644 --- a/lib/country_state_select.rb +++ b/lib/country_state_select.rb @@ -27,7 +27,12 @@ def self.states_collection(f, options) #Return the collected States for a given Country def self.collect_states(country) - CS.states(country).collect {|p| [ p[1], p[1] ] }.compact + CS.states(country).collect {|p| [ p[1], p[0] ] }.compact + end + + #Return the cities of given state and country + def self.collect_cities(state_id = '', country_id = '') + CS.cities(state_id.to_sym, country_id.to_sym) end #Return a hash for use in the simple_form diff --git a/spec/country_state_select_spec.rb b/spec/country_state_select_spec.rb index 7e2c56b..c90adf9 100644 --- a/spec/country_state_select_spec.rb +++ b/spec/country_state_select_spec.rb @@ -133,9 +133,9 @@ expect(method_call.class).to eq(Array) end - it "returns the same value for the key and value" do + it "returns the diffrent value for the key and value" do method_call = CountryStateSelect.collect_states('US') - expect(method_call.first.first).to eq(method_call.first.second) + expect(method_call.first.first).not_to eq(method_call.first.second) end it "returns the value part of the key-value pair" do @@ -149,4 +149,24 @@ end end + describe '#collect_cities' do + + it "returns an array" do + method_call = CountryStateSelect.collect_cities(:mp, :in) + expect(method_call.class).to eq(Array) + end + + it "it should return same value if city is not duplicate with state with out sending country" do + city_without_country = CountryStateSelect.collect_cities(:mp, '') + city_with_country = CountryStateSelect.collect_cities(:mp, :in) + expect(city_without_country).to eq(city_with_country) + end + + + it "returns an empty array if there are no states in that Country" do + method_call = CountryStateSelect.collect_cities('', '') + expect(method_call).to eq([]) + end + end + end \ No newline at end of file diff --git a/test/dummy/app/assets/javascripts/locations.coffee b/test/dummy/app/assets/javascripts/locations.coffee index 73fd59b..39823d4 100644 --- a/test/dummy/app/assets/javascripts/locations.coffee +++ b/test/dummy/app/assets/javascripts/locations.coffee @@ -1,2 +1,2 @@ $(document).on 'ready page:load', -> - CountryStateSelect({ chosen_ui: true, country_id: "location_test_country", state_id: "location_test_state" }) \ No newline at end of file + CountryStateSelect({ chosen_ui: true, country_id: "location_test_country", state_id: "location_test_state", city_id: "location_test_city" }) diff --git a/test/dummy/app/form/location_form.rb b/test/dummy/app/form/location_form.rb index 951b99c..9bcfa10 100644 --- a/test/dummy/app/form/location_form.rb +++ b/test/dummy/app/form/location_form.rb @@ -6,5 +6,6 @@ class LocationForm < Reform::Form property :test_country property :test_state + property :test_city end \ No newline at end of file diff --git a/test/dummy/app/views/locations/_form.html.erb b/test/dummy/app/views/locations/_form.html.erb index 549bd88..97e1cdb 100644 --- a/test/dummy/app/views/locations/_form.html.erb +++ b/test/dummy/app/views/locations/_form.html.erb @@ -4,6 +4,8 @@ <%= f.input :test_state, CountryStateSelect.state_options(label: "State / Province", form: f, field_names: { :country => :test_country, :state => :home_state } ) %> + <%= f.input :test_city, label: "State / Province" %> +

<%= f.button :submit %> diff --git a/test/dummy/db/migrate/20151024160724_add_test_city_to_locations.rb b/test/dummy/db/migrate/20151024160724_add_test_city_to_locations.rb new file mode 100644 index 0000000..1819b19 --- /dev/null +++ b/test/dummy/db/migrate/20151024160724_add_test_city_to_locations.rb @@ -0,0 +1,5 @@ +class AddTestCityToLocations < ActiveRecord::Migration + def change + add_column :locations, :test_city, :string + end +end diff --git a/test/dummy/db/schema.rb b/test/dummy/db/schema.rb index da984b4..b314f9f 100644 --- a/test/dummy/db/schema.rb +++ b/test/dummy/db/schema.rb @@ -11,13 +11,14 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20140724080030) do +ActiveRecord::Schema.define(version: 20151024160724) do create_table "locations", force: :cascade do |t| t.string "test_country" t.string "test_state" t.datetime "created_at" t.datetime "updated_at" + t.string "test_city" end end diff --git a/vendor/assets/javascript/country_state_select.js.erb b/vendor/assets/javascript/country_state_select.js.erb index fd023f2..b3d67c7 100644 --- a/vendor/assets/javascript/country_state_select.js.erb +++ b/vendor/assets/javascript/country_state_select.js.erb @@ -2,10 +2,15 @@ function CountryStateSelect(options) { var state_id = options['state_id']; var country_id = options['country_id']; + var city_id = options['city_id']; var state_name = $('#' + state_id).attr('name'); var state_class = $('#' + state_id).attr('class'); + var city_name = $('#' + city_id).attr('name'); + var city_class = $('#' + city_id).attr('class'); + + return statesDropdown(); // ====== ***** METHODS ***** ===================================================================== // @@ -14,10 +19,19 @@ function CountryStateSelect(options) { addChosenToCountry(); addChosenToState(); + addChosenToCity(); $("#" + country_id).change(function () { return findStates($(this).val()); }); + + } + + function citiesDropdown() { + $("#" + state_id).change(function () { + alert('asdf'); + return findCities($("#" + state_id).val(),$("#" + country_id).val()); + }); } function addChosenToState(){ @@ -26,10 +40,21 @@ function CountryStateSelect(options) { } } + function addChosenToCity(){ + + if (chosenIsRequired && cityIsNotText()) { + $('#' + city_id).chosen(); + } + } + function stateIsNotText(){ return !$('#' + state_id).is("[type=text]"); } + function cityIsNotText(){ + return !$('#' + city_id).is("[type=text]"); + } + function addChosenToCountry(){ if (chosenIsRequired) { $('#' + country_id).chosen(); @@ -42,6 +67,12 @@ function CountryStateSelect(options) { } } + function removeChosenFromCityFields(){ + if (chosenIsRequired) { + $("#" + options['city_id'] + "_chosen").remove(); + } + } + function chosenIsRequired(){ return options.hasOwnProperty("chosen_ui") && options['chosen_ui']; } @@ -62,6 +93,26 @@ function CountryStateSelect(options) { }); } + function findCities(state_id, country_id) { + + //Remove all Chosen from existing fields + removeChosenFromCityFields(); + + //Perform AJAX request to get the data; on success, build the dropdown + $.ajax({ + url: "/find_cities", + type: 'post', + + dataType: 'json', + cache: false, + data: { + country_id: country_id, + state_id: state_id + }, + success: function (data) { buildCitiesDropdown(data) } + }); + } + //Build the HTML for our dropdown menus function buildStatesDropdown(data) { @@ -71,7 +122,7 @@ function CountryStateSelect(options) { html = ''; @@ -84,6 +135,34 @@ function CountryStateSelect(options) { addChosenToState(); } + // [142] FIXME # Is there any other way to call city method , it is adding change method in every state change + if(typeof city_name !== "undefined" ){ + citiesDropdown(); + }; + + } + + function buildCitiesDropdown(data) { + console.log(data) + if (data.length === 0) { + html = ''; + } else { + html = ''; + } + + $('#' + city_id).replaceWith(html); + + //This has to happen AFTER we've replaced the dropdown or text + if (data.length > 0) { + addChosenToCity(); + } + } } \ No newline at end of file