Santiago Santiago - 4 years ago 113
jQuery Question

Country/state/city depedent select with json & jquery

I want to create a cascade dropdowns for country state and city. I want to also populate the city dropdown, so far country and state are ok, what am i missing?
This is what i got so far:

<form id="dropdowns" action="index.html">

<label>Country:</label>
<select id="country" name="country">
<option value="000">-Select Country-</option>
</select>

<br />

<label>State:</label>
<select id="state" name="network">
<option value="000">-Select State-</option>
</select>

<br />

<label>City:</label>
<select id="model" name="model">
<option value="000">-Select City-</option>
</select>

<br />

</form>


This is what i'm using for test purposes:

var myJson = {
"country": [
{
"name": "United States",
"id": "usa",
"states": [
{
"name": "State 1 USA",
"id": "usaState1",
"cities": [
{
"name": "City 1",
"id": "usaState1City1",
"area": "12345 sqkm"
},
{
"name": "City 2",
"id": "usaState1City2",
"area": "12345 sqkm"
}
]
},
{
"name": "State 2 USA",
"id": "usaState2",
"cities": [
{
"name": "City 3",
"id": "usaState2City3",
"area": "12345 sqkm"
},
{
"name": "City 4",
"id": "usaState2City4",
"area": "12345 sqkm"
}
]
}
]
},
{
"name": "Australia",
"id": "aus",
"states": [
{
"name": "State 1 Australia",
"id": "ausState1",
"cities": [
{
"name": "City 5",
"id": "ausState1City5",
"area": "12345 sqkm"
},
{
"name": "City 6",
"id": "ausState1City6",
"area": "12345 sqkm"
}
]
},
{
"name": "State 2 Australia",
"id": "ausState2",
"cities": [
{
"name": "City 7",
"id": "ausState2City7",
"area": "12345 sqkm"
},
{
"name": "City 8",
"id": "ausState2City8",
"area": "12345 sqkm"
}
]
}
]
}
]
}


And this is the jquery script:

$.each(myJson.country, function (index, value) {
$("#country").append('<option value="'+value.id+'">'+value.name+'</option>');
});

$('#country').on('change', function(){
console.log($(this).val());
for(var i = 0; i < myJson.country.length; i++)
{
if(myJson.country[i].id == $(this).val())
{
$('#state').html('<option value="000">-Select State-</option>');
$.each(myJson.country[i].states, function (index, value) {
$("#state").append('<option value="'+value.id+'">'+value.name+'</option>');
});
}
}
});


I can't get it work:

$('#state').on('change', function(){
console.log($(this).val());
for(var i = 0; i < myJson.country.length; i++)
{
if(myJson.country[i].states.id == $(this).val())

{
//console.log(myJson.country[i].states.id);
$('#model').html('<option value="000">Cities</option>');
$.each(myJson.country[i].states.cities, function (index, value) {
$("#model").append('<option value="'+value.id+'">'+value.name+'</option>');
});
}
}
});

Answer Source

You'll need another nested loop in your change function for state. You are referencing myJson.country[i].states.id. But myJson.country[i].states is an array. It doesn't have an id attribute. You will need to loop through that array and find all cities with a matching state id. I would recomment flattening your object into a list of cities with an associated state id; Try something like this:

function getCities() {
    var cities = [];
    for(var i = 0; i < myJson.country.length; i++) {
      var country = myJson.country[i];
      for(var j = 0; j < country.states.length; j++) {
          var state = country.states[j];
          for (var k = 0; k < state.cities.length; k++) {
            var city = state.cities[k];
            cities.push({
                stateId: state.id,
                stateName: state.name,
                cityId: city.id,
                cityName: city.name
            });
          }
      }
    }
    return cities;
}

And then use this in your state change event:

  $('#state').on('change', function(){
    console.log($(this).val());
    var cities = getCities();
    $('#model').html('<option value="000">-Select State-</option>');
    var stateId = $(this).val();
    $.each(cities, function (index, value) {
      if (value.stateId == stateId) {
        $("#model").append('<option value="'+value.cityId +'">'+value.cityName+'</option>');
      }
    });
  });

Working example: https://jsfiddle.net/mspinks/40916zn4/7/

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download