Pluginn to create country dropdown > poulated city drop down

Does anyone know of a pluginn to create a country dropdown followed by a city dropdown, based on the choice in the country drop down?

Thank you in advance.

I have chosen to take a slightly different approach. I now have a country drop down and a state drop down (populated after a country is chosen) For this I use two arrays, one for the countries and one for the states, plus the two following functions to populate the two drop down menus.


function print_country(country_id){
	// given the id of the <select> tag as function argument, it inserts <option> tags
	var option_str = document.getElementById(country_id);
	var x, i=0;
	for(x in country_arr){
		option_str.options[i++] = new Option(country_arr[x],country_arr[x]);
	}
}

function print_state(state_id, state_index){
	var option_str = document.getElementById(state_id);
	var x, i=0; state_index++;
	var state_arr = s_a[state_index].split("|");
	for(x in state_arr){
            option_str.options[i++] = new Option(state_arr[x],state_arr[x]);
	}
}

And this are my se;ect boxes in the page


Country: <select onchange="print_state('state',this.selectedIndex);" id="country" name ="country"></select>
City/District/State: <select name ="state" id ="state"></select>
<script language="javascript">print_country("country");</script>

The way it is now, the first country from the country array is selected. I actually would like to have an empty value first with something like Choose a Country. But I have no idea what to change in the print_country function to make that happen. Probably for everyone in this forum this will be piece of cake but not for me :frowning:

Any help would be very much appreciated.

Let’s start with the country and state select boxes. There’s no need to store the countries in an array, as they’re not going to change and you don’t want to leave the non-scripting situations without a solution.


<form id="location">
    Country: <select name="country">
        <option>Please select a country</option>
        <option>Abkhazia</option>
        ...
        <option>Zimbabwe</option>
    </select>
    City/District/State: <input name="state">
</form>

That provides for a worst-case scenario, where someone can select their country and then type in the city/district/state

What shall we do when scripting is available? We can adjust the city/district/state so that the select is added, with the input field following it so that people can type theirs in if they cannot find it in the select list. Notice also that the input is renamed to be “otherState” instead of the earlier “state” so that it won’t conflict with the selected state.


.hidden {
    display: none;
}

City/District/State: <select name="state" class="hidden"><input name="otherState">

This way it won’t impair anyone without scripting, and can be scripted to be made available on an as-needed basis.

We need to set an onchange event to the country select, which will check if the state select needs to be added, and then updates the state selectbox.


var state_arr = {
    'Abkhazia': ['Gagra', 'Gali', 'Gudauta', 'Gulripsh', 'Ochamchira', 'Sukhumi', 'Tquarchal'],
    'Zimbabwe': ['Mashonaland Central Province', 'Mashonaland East Province', 'Matabeleland North Province', 'Matabeleland South Province', 'Masvingo Province']
},
    form = document.getElementById('register');

form.elements.country.onchange = countryUpdate;
form.elements.state.onchange = stateUpdate;

The countryUpdate function has three main tasks to do. First it clears out any old state options, then it creates new state options based on the selected country. The last thing it takes care of is deciding whether the state selectbox should be shown, before triggering its onchange event so that the otherState field can be appropriately shown/hidden too.



function countryUpdate() {
    var states = state_arr[this.value] || [],
        stateSelect = form.elements.state,
        i,
	option;

    while (stateSelect.options.length > 0) {
        stateSelect.removeChild(stateSelect.firstChild);
    }

    states.push('Other');
    for (i = 0; i < states.length; i += 1) {
	option = document.createElement('option');
	option.appendChild(document.createTextNode(states[i]));
        stateSelect.appendChild(option);
    }

    stateSelect.className = (this.selectedIndex > 0) ? '' : 'hidden';
    stateSelect.onchange();
}

Because the countryUpdate function adds the Other field as the very last item in the select, the stateUpdate function just needs to check if it is that very last option which is selected. If it is, the otherState field should be shown. If anything else is selected, the otherState field should be hidden.



function stateUpdate() {
    var stateSelect = this.form.elements.state,
	isOther = (stateSelect.selectedIndex === this.options.length - 1);
        stateInput = this.form.elements.otherState,

    stateInput.className = (isOther) ? '' : 'hidden';
}

And that’s the start of a basic but functional country/state selection, that caters for several different scenarios.

A potential further option from here is to use Ajax to retrieve the state_arr data from your server (caching the values to help reduce return trips) whenever the country is changed.

Here’s some test code that puts things in to action.


[color="blue"]<html>
<head>
<style>[/color]
[color="magenta"].hidden {
    display: none;
}[/color]
[color="blue"]</style>
</head>
<body>
<form id="register">
    Country: <select name="country">
        <option>Please select a country</option>
        <option>Abkhazia</option>
        ...
        <option>Zimbabwe</option>
    </select>
    City/District/State: <select name="state" class="hidden"><input name="otherState">
    <input type="submit">
</form>
<script>[/color]
[color="green"]function countryUpdate() {
    var states = state_arr[this.value] || [],
        stateSelect = form.elements.state,
        i,
	option;

    while (stateSelect.options.length > 0) {
        stateSelect.removeChild(stateSelect.firstChild);
    }

    states.push('Other');
    for (i = 0; i < states.length; i += 1) {
	option = document.createElement('option');
	option.appendChild(document.createTextNode(states[i]));
        stateSelect.appendChild(option);
    }

    stateSelect.className = (this.selectedIndex > 0) ? '' : 'hidden';
    stateSelect.onchange();
}
function stateUpdate() {
    var stateSelect = this.form.elements.state,
	isOther = (stateSelect.selectedIndex === this.options.length - 1);
        stateInput = this.form.elements.otherState,

    stateInput.className = (isOther) ? '' : 'hidden';
}

var state_arr = {
    'Abkhazia': ['Gagra', 'Gali', 'Gudauta', 'Gulripsh', 'Ochamchira', 'Sukhumi', 'Tquarchal'],
    'Zimbabwe': ['Mashonaland Central Province', 'Mashonaland East Province', 'Matabeleland North Province', 'Matabeleland South Province', 'Masvingo Province']
},
    form = document.getElementById('register');

form.elements.country.onchange = countryUpdate;
form.elements.state.onchange = stateUpdate;[/color]
[color="blue"]</script>
</body>
</html>[/color]