Chain select (javascript)

Sometimes you have two select boxes and you want to fill the second one with options depending on the user's selection in the first box. This demo just uses javascript. It can also be done with AJAX if you need to get the options from a database.

Here's what I'm talking about:

The HTML looks like this:

HTML
<form method="post" action="#">
<p><label>country: <select id="country" name="country">
</select></label>
<label>city: <select id="city" name="city">
</select></label></p>
</form>

The boxes are empty because the javacript fills them.

In the javascript, first, the options are declared as arrays:

javascript
var countries=new Array();

countries[0]=new Array();
countries[0]['country']='United Kingdom';
countries[0]['cities']=['London','Manchester','Birmingham','Liverpool','Edinburgh','Cardiff','Belfast'];
countries[1]=new Array();
countries[1]['country']='United States';
countries[1]['cities']=['Washington DC','New York','Los Angeles','Chicago'];
countries[2]=new Array();
countries[2]['country']='Australia';
countries[2]['cities']=['Canberra','Melbourne','Sydney','Brisbane'];
countries[3]=new Array();
countries[3]['country']='Japan';
countries[3]['cities']=['Tokyo','Osaka','Fukuoka','Sendai','Sapporo'];

There's a function to set up the boxes and to assign an onchange event to the first box.

javascript
function initBoxes(box1,box2) {
var country=document.getElementById(box1);
var city=document.getElementById(box2);
for (i=0; i<countries.length; i++) {
  var x=document.createElement('option');
  var y=document.createTextNode(countries[i]['country']);
  if (window.attachEvent) { // for IE
  x.setAttribute('value',y.nodeValue);
  }
  x.appendChild(y);
  country.appendChild(x);
}

country.onchange=function() {
  if(this.value!="") {
   var list=document.getElementById(box2);
   while (list.childNodes[0]) {
    list.removeChild(list.childNodes[0])
   }
   fillBox2(city,this.value);
   }
  }

fillBox2(city,country.value);
}

You can see that that function calls another function called 'fillBox2()'. That looks like this:

javascript
function fillBox2(box2,country) {
for (i=0; i<countries.length; i++) {
  if (countries[i]['country']==country) {
   var cities=countries[i]['cities'];
  }
}
for (i=0; i<cities.length; i++) {
  var x=document.createElement('option');
  var y=document.createTextNode(cities[i]);
  x.appendChild(y);
  box2.appendChild(x);
  }
}

This is called onload like this:

javascript
window.onload=function() {initBoxes('country','city');}

Comments

#1
2007-05-11 sam says :

this script is great, you should link it on the menu !

do you think it would be difficult to add more levels, for example, you would select the country, then the state, county etc.. ?

#2
2007-05-11 Sam says :

<<--
yeah, i was mentioning the Ajax version actually !

#3
2007-05-18 BonRouge says :

Sam,
Yes, it is possible...
(I'm afraid I haven't had time to show how though frown).

#4
2007-06-16 ACB says :

This presents error in box2 at ie 6.0

#5
2007-06-17 ACB says :

at fillbox2:
for (i=1; i<cities.length; i++) { --- eliminates the first array occurency.
the first index must be 0
correct command: for (i=0; i<cities.length; i++)

#6
2007-08-23 GM says :

Hey guyz,
this is a cool example.. thanks!
but this script has issues with IE... it shows empty box in IE... if I set to view the errors on the page.. even this page pops up JS errors...

The Error says: 'length' is null or not an object..

#7
2007-08-27 GM says :

all fixed.. cool & thanks! smile

#8
2007-09-08 Andrew says :

Have you noticed that the first city is never available? For example, London does not display under United Kingdom...

#9
2007-09-09 BonRouge says :

Andrew,
Thanks for pointing that out. I hadn't noticed that. It was just a small mistake - a '1' where there should have been a '0'.
Fixed it now. smile

#10
2007-09-11 Andrew says :

Easy enough. What about if you wanted to submit values that were not the same as the displayed option? For example, how could you submit numerical values for the cities - London as "1", Manchester as "2" ?

#11
2007-09-11 BonRouge says :

Andrew,
To do that, you just need to add this line: x.value=i+1;...and this bit for IE: if (window.attachEvent) { // for IE
x.setAttribute('value',i+1);
}

...here:function fillBox2(box2,country) {
for (i=0; i<countries.length; i++) {
if (countries[ i ]['country']==country) {
var cities=countries[ i ]['cities'];
}
}
for (i=0; i<cities.length; i++) {
var x=document.createElement('option');
var y=document.createTextNode(cities[ i ]);
x.value=i;
if (window.attachEvent) { // for IE
x.setAttribute('value',i+1);
}
x.appendChild(y);
box2.appendChild(x);
}
}

#12
2008-02-01 shez says :

You could just use php + Ajax. of even if you dont know Ajax you could use PHP but it would cost you a click or two (ie you would have to press submit to get all cities related to your country

#13
2008-05-06 Amir says :

There is a way that i can send var to the page
list a defualt country and city to show first ?
or if i want to update a page so the country and city already selected ??

#14
2008-06-07 Naseer Ahmad says :

Hi,
i have used this code and find very useful.

only one this i need is that when i want to give custom values

like in Cities currently only numbers are shown...
but i want to show the specified values
like, LON for London, and so on....

How can i implement that

regards,
Naseer Ahmad

#15
2008-09-15 HARDIK says :

HEY I COPY PASTED THE WHOLE CODE BUT THIS IS NOT WORKING ONLY THE COUNTRIES ARE LISTED IN THE OPTION AND THE CITIES ARE NOT LISTED PLEASE HELP.........

#16
2008-10-04 kristin says :

I am having the same problem as GM above. Script works great except for in IE. Select boxes are blank, won't populate. Any fix?

#17
2008-10-28 john says :

Your site is very interesting and useful

#18
2008-12-04 ayyaps says :

this example is very nice. hats off

#19
2008-12-12 Jos says :

I used the script. But the e field 'city' is empty when i have it check after a submit

#20
2008-12-27 david-js says :

Cool. And if you insert new array value:
countries[0]['citiescode']=['333','352','361','370','374','378','382'];

And want to submit these values for cities?

Thanks!

#21
2009-02-07 moh3 says :

thanks for your great work but can you please point out how to do this to submit information from the select menu into a div beneath it

#22
2009-02-15 Leon says :

when checked on IE, it gives this error;
length is 'null' or not an object on line 30, character 11. Only countries are displayed as mentioned above and cities wouldn't show up.
This is a great and I need it to be working also in IE as well as Firefox?
I tried the code you gave above but wouldn't work here unfortunately.
Any help is appreciated
thanks and keep up the great work

#23
2009-02-16 mili says :

Hello, I need to remember selected values after form is sent. Can you let me know, how to do it ? Something on the way html selected="selected"...

Thanks in advance.

#24
2009-02-19 at says :

Hi,

i dont understand how to put the code together.
shall i copy/paste it to an html file? 2 seperate files?
which code goes first, javascript or html.Please help me.

Thanks,
atn

#25
2009-02-20 BonRouge says :

moh3,
See if this helps.

#26
2009-03-18 DavidS says :

This script is exactly what I was looking for. Thanks.
I've used php to fill the arrays from a db. It's working well in FF and IE.

Question: How do I pre select elements? In http this is SELECTED but how can I do this in the java script?

David.

#27
2009-03-18 shrix says :

vry bad coding dude...itz just useless...u hvn't cared abt the IE 6.0

#28
2009-03-19 DavidS says :

Re: Pre selection (see above)
I've worked this out now for anyone who is interested.

after:
country.appendChild(x);
}
Add:
country.options[n].selected=true;

and after:
box2.appendChild(x);
}
add:
box2.options[n].selected=true;

where n = the element you want pre selected.

#29
2009-03-27 Bob says :

Great Site - really useful information!

#30
2009-05-21 cipu says :

hi,

is this work with php _POST ?

thanks

#31
2009-05-27 BonRouge says :

cipu,
Yes.

Comment form

Please type the word 'whisky' here:

BB code available :

  • [b]...[/b] : bold
  • [it]...[/it] : italic
  • [q]...[/q] : quote
  • [c]...[/c] : code
  • [url=...]...[/url] : url