Skip to content

Commit

Permalink
Added city select in to the country state select :)
Browse files Browse the repository at this point in the history
  • Loading branch information
arvindvyas committed Oct 24, 2015
1 parent bf12d02 commit ef3b2a0
Show file tree
Hide file tree
Showing 10 changed files with 132 additions and 9 deletions.
9 changes: 9 additions & 0 deletions app/controllers/country_state_select/cscs_controller.rb
Expand Up @@ -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
7 changes: 4 additions & 3 deletions 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
7 changes: 6 additions & 1 deletion lib/country_state_select.rb
Expand Up @@ -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
Expand Down
24 changes: 22 additions & 2 deletions spec/country_state_select_spec.rb
Expand Up @@ -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
Expand All @@ -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
2 changes: 1 addition & 1 deletion 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" })
CountryStateSelect({ chosen_ui: true, country_id: "location_test_country", state_id: "location_test_state", city_id: "location_test_city" })
1 change: 1 addition & 0 deletions test/dummy/app/form/location_form.rb
Expand Up @@ -6,5 +6,6 @@ class LocationForm < Reform::Form

property :test_country
property :test_state
property :test_city

end
2 changes: 2 additions & 0 deletions test/dummy/app/views/locations/_form.html.erb
Expand Up @@ -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" %>

<br /><br />

<%= f.button :submit %>
Expand Down
@@ -0,0 +1,5 @@
class AddTestCityToLocations < ActiveRecord::Migration
def change
add_column :locations, :test_city, :string
end
end
3 changes: 2 additions & 1 deletion test/dummy/db/schema.rb
Expand Up @@ -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
81 changes: 80 additions & 1 deletion vendor/assets/javascript/country_state_select.js.erb
Expand Up @@ -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 ***** ===================================================================== //
Expand All @@ -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(){
Expand All @@ -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();
Expand All @@ -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'];
}
Expand All @@ -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) {

Expand All @@ -71,7 +122,7 @@ function CountryStateSelect(options) {
html = '<select id="' + state_id + '" name="' + state_name + '" class="' + state_class + '" >';

for (i = 0; i < data.length; i++) {
html += '<option>' + data[i][1] + '</option>';
html += '<option value='+data[i][0]+'>' + data[i][1] + '</option>';
}

html += '</select>';
Expand All @@ -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 = '<input id="' + city_id + '" name="' + city_name + '" class="' + city_class + '" type="text" type="text" value="" >';
} else {
html = '<select id="' + city_id + '" name="' + city_name + '" class="' + city_class + '" >';

for (i = 0; i < data.length; i++) {
html += '<option>' + data[i] + '</option>';
}

html += '</select>';
}

$('#' + city_id).replaceWith(html);

//This has to happen AFTER we've replaced the dropdown or text
if (data.length > 0) {
addChosenToCity();
}

}

}

0 comments on commit ef3b2a0

Please sign in to comment.