13
votes

i have the following problem:

I started to create a form with HTML an JS and there are two Dropdowns (Country and City). now i want to make these two dynamic with JQuery so that only the cities of the selected countries are visible.

I've started with some basic JS which worked fine but makes some trouble in IE. Now i'm trying to convert my JS to JQuery for a better compatibility.

My original JS looks like this:

function populate(s1, s2) {
    var s1 = document.getElementById(s1);
    var s2 = document.getElementById(s2);
    s2.innerHTML = "";
    if (s1.value == "Germany") {
        var optionArray = ["|", "magdeburg|Magdeburg", "duesseldorf|Duesseldorf", "leinfelden-echterdingen|Leinfelden-Echterdingen", "eschborn|Eschborn"];
    } else if (s1.value == "Hungary") {
        var optionArray = ["|", "pecs|Pecs", "budapest|Budapest", "debrecen|Debrecen"];
    } else if (s1.value == "Russia") {
        var optionArray = ["|", "st. petersburg|St. Petersburg"];
    } else if (s1.value == "South Africa") {
        var optionArray = ["|", "midrand|Midrand"];
    } else if (s1.value == "USA") {
        var optionArray = ["|", "downers grove|Downers Grove"];
    } else if (s1.value == "Mexico") {
        var optionArray = ["|", "puebla|Puebla"];
    } else if (s1.value == "China") {
        var optionArray = ["|", "beijing|Beijing"];
    } else if (s1.value == "Spain") {
        var optionArray = ["|", "barcelona|Barcelona"];
    }

    for (var option in optionArray) {
        var pair = optionArray[option].split("|");
        var newOption = document.createElement("option");
        newOption.value = pair[0];
        newOption.innerHTML = pair[1];
        s2.options.add(newOption);
    }
};

and here my Jquery:

http://jsfiddle.net/HvXSz/

i know it is very simple but i can't see the wood for the trees.

5
your fiddle was not working jsfiddle.net/arunpjohny/2pza5/1Arun P Johny

5 Answers

46
votes

It should as simple as

jQuery(function($) {
    var locations = {
        'Germany': ['Duesseldorf', 'Leinfelden-Echterdingen', 'Eschborn'],
        'Spain': ['Barcelona'],
        'Hungary': ['Pecs'],
        'USA': ['Downers Grove'],
        'Mexico': ['Puebla'],
        'South Africa': ['Midrand'],
        'China': ['Beijing'],
        'Russia': ['St. Petersburg'],
    }

    var $locations = $('#location');
    $('#country').change(function () {
        var country = $(this).val(), lcns = locations[country] || [];

        var html = $.map(lcns, function(lcn){
            return '<option value="' + lcn + '">' + lcn + '</option>'
        }).join('');
        $locations.html(html)
    });
});

Demo: Fiddle

13
votes

I'm going to provide a second solution, as this post is still up in Google search for 'jquery cascade select'. This is the first select:

<select class="select" id="province" onchange="filterCity();">
  <option value="1">RM</option>
  <option value="2">FI</option>
</select>

and this is the second, disabled until the first is selected:

<select class="select" id="city" disabled>
  <option data-province="RM" value="1">ROMA</option>
  <option data-province="RM" value="2">ANGUILLARA SABAZIA</option>
  <option data-province="FI" value="3">FIRENZE</option>
  <option data-province="FI" value="4">PONTASSIEVE</option>
</select>

this one is not visible, and acts as a container for all the elements filtered out by the selection:

<span id="option-container" style="visibility: hidden; position:absolute;"></span>

Finally, the script that filters:

<script>

    function filterCity(){
      var province = $("#province").find('option:selected').text(); // stores province
      $("#option-container").children().appendTo("#city"); // moves <option> contained in #option-container back to their <select>
      var toMove = $("#city").children("[data-province!='"+province+"']"); // selects city elements to move out
      toMove.appendTo("#option-container"); // moves city elements in #option-container
      $("#city").removeAttr("disabled"); // enables select
};
</script>
6
votes

I have created cascading Dropdown for Country, State, City and Zip

It may helpful to someone. Here only some portion of code are posted you can see full working example on jsfiddle.

//Get html elements
var countySel = document.getElementById("countySel");
var stateSel = document.getElementById("stateSel"); 
var citySel = document.getElementById("citySel");
var zipSel = document.getElementById("zipSel");

//Load countries
for (var country in countryStateInfo) {
    countySel.options[countySel.options.length] = new Option(country, country);
}

//County Changed
countySel.onchange = function () {

     stateSel.length = 1; // remove all options bar first
     citySel.length = 1; // remove all options bar first
     zipSel.length = 1; // remove all options bar first

     if (this.selectedIndex < 1)
         return; // done

     for (var state in countryStateInfo[this.value]) {
         stateSel.options[stateSel.options.length] = new Option(state, state);
     }
}

Fiddle Demo

0
votes
I have a handy code. you can just copy it: 
Same as above


<html>
    <head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
    <script>
jQuery(function($) {
    var locations = {
        'Germany': ['Duesseldorf', 'Leinfelden-Echterdingen', 'Eschborn', 'asdasdasd'],
        'Spain': ['Barcelona'],
        'Hungary': ['Pecs'],
        'USA': ['Downers Grove'],
        'Mexico': ['Puebla'],
        'South Africa': ['Midrand'],
        'China': ['Beijing'],
        'Japn': ['tokyo'],
        'Shuidong': ['shuidongjie','maomingjie'],
        'Russia': ['St. Petersburg'],
    }

    var $locations = $('#location');
    $('#country').change(function () {
        var country = $(this).val(), lcns = locations[country] || [];

        var html = $.map(lcns, function(lcn){
            return '<option value="' + lcn + '">' + lcn + '</option>'
        }).join('');
        $locations.html(html)
    });
});
</script>
</head>
<body>1
<label class="page1">Country</label>
<div class="tooltips" title="Please select the country that the customer will primarily be served from">
    <select id="country" name="country" placeholder="Phantasyland">
        <option></option>
        <option>Germany</option>
        <option>Spain</option>
        <option>Hungary</option>
        <option>USA</option>
        <option>Mexico</option>
        <option>South Africa</option>
        <option>China</option>
        <option>Japn</option>
        <option>Shuidong</option>
        <option>Russia</option>

    </select>
</div>
<br />
<br />
<label class="page1">Location</label>
<div class="tooltips" title="Please select the city that the customer is primarily to be served from.">
    <select id="location" name="location" placeholder="Anycity"></select>
</div>
</body>
</html>
0
votes

This is an example that I've done. I wish that will be useful for you.

$(document).ready(function(){

    var ListNiveauCycle = [{"idNiveau":1,"libelleNiveau":"CL1","idCycle":1},{"idNiveau":26,"libelleNiveau":"Niveau 22","idCycle":24},{"idNiveau":34,"libelleNiveau":"CL3","idCycle":1},{"idNiveau":35,"libelleNiveau":"DAlf3","idCycle":1}];
    console.log(ListNiveauCycle);
	
	
	function remplirListNiveau(idCycle){
			console.log('remplirListNiveau');
			var $niveauSelect = $("#niveau");
			// vider la liste
			$niveauSelect.empty();
			 for (var i = 0; i < ListNiveauCycle.length; i++) {
				 			if(ListNiveauCycle[i].idCycle==idCycle){
		                        var opt1 = document.createElement('option');
		                        opt1.innerHTML = ListNiveauCycle[i].libelleNiveau;
		                        opt1.value = ListNiveauCycle[i].idNiveau;
		                        $niveauSelect.append(opt1);
		                        }
		                    }
	}
	
	$("#cycles").change(function(){
		remplirListNiveau(this.value)
	});
	
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="form-group row">
                          <label class="col-sm-3 col-form-label">Cycle</label>
                          <div class="col-sm-9">
                            <select class="form-control" id="cycles" required="">
                              <option value="">-----------</option>
    						  <option value="1">Cycle1</option>
    						  <option value="24">Cycle2</option>
                            </select>
                          </div>
                        </div>
         
         <div class="col-md-4">
                        <div class="form-group row">
                          <label class="col-sm-3 col-form-label">Niveau</label>
                          <div class="col-sm-9">
                            <select id="niveau" class="form-control" required="" name="niveau.id">
                            </select>
                          </div>
                        </div>
                      </div>