Trying to add 4th level to chained select

I found this code and am trying to add a fourth level for it but cant seem to get it to work

// Chained Selects

// Copyright Xin Yang 2004
// Web Site: [www.yxScripts.com](http://www.yxScripts.com)
// EMail: [email]m_yangxin@hotmail.com[/email]
// Last Updated: 2004-08-23

// This script is free as long as the copyright notice remains intact.

var _disable_empty_list=false;
var _hide_empty_list=false;

// ------
if (typeof(disable_empty_list)=="undefined") { disable_empty_list=_disable_empty_list; }
if (typeof(hide_empty_list)=="undefined") { hide_empty_list=_hide_empty_list; }

var cs_goodContent=true, cs_M="M", cs_L="L", cs_curTop=null, cs_curSub=null;

function cs_findOBJ(obj,n) {
  for (var i=0; i<obj.length; i++) {
    if (obj[i].name==n) { return obj[i]; }
  }
  return null;
}
function cs_findContent(n) { return cs_findOBJ(cs_content,n); }

function cs_findM(m,n) {
  if (m.name==n) { return m; }

  var sm=null;
  for (var i=0; i<m.items.length; i++) {
    if (m.items[i].type==cs_M) {
      sm=cs_findM(m.items[i],n);
      if (sm!=null) { break; }
    }
  }
  return sm;
}
function cs_findMenu(n) { return (cs_curSub!=null && cs_curSub.name==n)?cs_curSub:cs_findM(cs_curTop,n); }

function cs_contentOBJ(n,obj){ this.name=n; this.menu=obj; this.lists=new Array(); this.cookie=""; }; cs_content=new Array();
function cs_topmenuOBJ(tm) { this.name=tm; this.items=new Array(); this.df=0; this.addM=cs_addM; this.addL=cs_addL; }
function cs_submenuOBJ(dis,link,sub) {
  this.name=sub;
  this.type=cs_M; this.dis=dis; this.link=link; this.df=0;

  var x=cs_findMenu(sub);
  this.items=x==null?new Array():x.items;

  this.addM=cs_addM; this.addL=cs_addL;
}
function cs_linkOBJ(dis,link) { this.type=cs_L; this.dis=dis; this.link=link; }

function cs_addM(dis,link,sub) { this.items[this.items.length]=new cs_submenuOBJ(dis,link,sub); }
function cs_addL(dis,link) { this.items[this.items.length]=new cs_linkOBJ(dis,link); }

function cs_showMsg(msg) { window.status=msg; }
function cs_badContent(n) { cs_goodContent=false; cs_showMsg("["+n+"] Not Found."); }

function cs_optionOBJ(text,value) { this.text=text; this.value=value; }
function cs_emptyList(list) { for (var i=list.options.length-1; i>=0; i--) { list.options[i]=null; } }
function cs_refreshList(list,opt,df) {
  cs_emptyList(list);

  for (var i=0; i<opt.length; i++) {
    list.options[i]=new Option(opt[i].text, opt[i].value);
  }

  if (opt.length>0) {
    list.selectedIndex=df;
  }
}
function cs_getOptions(menu) {
  var opt=new Array();
  for (var i=0; i<menu.items.length; i++) {
    opt[i]=new cs_optionOBJ(menu.items[i].dis, menu.items[i].link);
  }
  return opt;
}
function cs_updateListGroup(content,idx,sidx,mode) {
  var i=0, curItem=null, menu=content.menu;

  while (i<idx) {
    menu=menu.items[content.lists[i++].selectedIndex];
  }

  if (menu.items[sidx].type==cs_M && idx<content.lists.length-1) {
    var df=cs_getIdx(mode,content.cookie,idx+1,menu.items[sidx].df);

    cs_refreshList(content.lists[idx+1], cs_getOptions(menu.items[sidx]), df);
    if (content.cookie) {
      cs_setCookie(content.cookie+"_"+(idx+1),df);
    }

    if (idx+1<content.lists.length) {
      if (disable_empty_list) {
        content.lists[idx+1].disabled=false;
      }
      if (hide_empty_list) {
        content.lists[idx+1].style.display="";
      }

      cs_updateListGroup(content,idx+1,df,mode);
    }
  }
  else {
    for (var s=idx+1; s<content.lists.length; s++) {
      cs_emptyList(content.lists[s]);

      if (disable_empty_list) {
        content.lists[s].disabled=true;
      }
      if (hide_empty_list) {
        content.lists[s].style.display="none";
      }

      if (content.cookie) {
        cs_setCookie(content.cookie+"_"+s,"");
      }
    }
  }
}
function cs_initListGroup(content,mode) {
  var df=cs_getIdx(mode,content.cookie,0,content.menu.df);

  cs_refreshList(content.lists[0], cs_getOptions(content.menu), df);
  if (content.cookie) {
    cs_setCookie(content.cookie+"_"+0,df);
  }

  cs_updateListGroup(content,0,df,mode);
}

function cs_updateList() {
  var content=this.content;
  for (var i=0; i<content.lists.length; i++) {
    if (content.lists[i]==this) {
      if (content.cookie) {
        cs_setCookie(content.cookie+"_"+i,this.selectedIndex);
      }

      if (i<content.lists.length-1) {
        cs_updateListGroup(content,i,this.selectedIndex,"");
      }
    }
  }
}

function cs_getIdx(mode,name,idx,df) {
  if (mode) {
    var cs_idx=cs_getCookie(name+"_"+idx);
    if (cs_idx!="") {
      df=parseInt(cs_idx);
    }
  }
  return df;
}

function _setCookie(name, value) {
  document.cookie=name+"="+value;
}
function cs_setCookie(name, value) {
  setTimeout("_setCookie('"+name+"','"+value+"')",0);
}

function cs_getCookie(name) {
  var cookieRE=new RegExp(name+"=([^;]+)");
  if (document.cookie.search(cookieRE)!=-1) {
    return RegExp.$1;
  }
  else {
    return "";
  }
}

// ----
function addListGroup(n,tm) {
  if (cs_goodContent) {
    cs_curTop=new cs_topmenuOBJ(tm); cs_curSub=null;

    var c=cs_findContent(n);
    if (c==null) {
      cs_content[cs_content.length]=new cs_contentOBJ(n,cs_curTop);
    }
    else {
      delete(c.menu); c.menu=cs_curTop;
    }
  }
}

function addList(n,dis,link,sub,df) {
  if (cs_goodContent) {
    cs_curSub=cs_findMenu(n);

    if (cs_curSub!=null) {
      cs_curSub.addM(dis,link||"",sub);
      if (typeof(df)!="undefined") { cs_curSub.df=cs_curSub.items.length-1; }
    }
    else {
      cs_badContent(n);
    }
  }
}

function addOption(n,dis,link,df) {
  if (cs_goodContent) {
    cs_curSub=cs_findMenu(n);

    if (cs_curSub!=null) {
      cs_curSub.addL(dis,link||"");
      if (typeof(df)!="undefined") { cs_curSub.df=cs_curSub.items.length-1; }
    }
    else {
      cs_badContent(n);
    }
  }
}

function initListGroup(n) {
  var _content=cs_findContent(n), count=0;
  if (_content!=null) {
    content=new cs_contentOBJ("cs_"+n,_content.menu);
    cs_content[cs_content.length]=content;

    for (var i=1; i<initListGroup.arguments.length; i++) {
      if (typeof(arguments[i])=="object" && arguments[i].tagName && arguments[i].tagName=="SELECT") {
        content.lists[count]=arguments[i];

        arguments[i].onchange=cs_updateList;
        arguments[i].content=content; arguments[i].idx=count++;
      }
      else if (typeof(arguments[i])=="string" && /^[a-zA-Z_]\\w*$/.test(arguments[i])) {
        content.cookie=arguments[i];
      }
    }

    if (content.lists.length>0) {
      cs_initListGroup(content,content.cookie);
    }
  }
}

function resetListGroup(n) {
  var content=cs_findContent("cs_"+n);
  if (content!=null && content.lists.length>0) {
    cs_initListGroup(content,"");
  }
}
// ------

//var hide_empty_list=true; //uncomment this line to hide empty selection lists

var disable_empty_list=true; //uncomment this line to disable empty selection lists

addListGroup("vehicles", "car-makers");

addOption("car-makers", "Select a maker", "", "", 1); //Empty starter option
addList("car-makers", "Toyota", "Toyota", "Toyota");
addList("car-makers", "Honda", "Honda", "Honda");
addList("car-makers", "Chrysler", "Chrysler", "Chrysler");

addOption("Toyota", "Select vehicle type", "", "", 1); //Empty starter option
addList("Toyota", "Cars", "car", "Toyota-Cars");
addList("Toyota", "SUVs/Van", "suv", "Toyota-SUVs/Van");
addList("Toyota", "Trucks", "truck", "Toyota-Trucks");

addOption("Toyota-Cars", "Select a model", "");
addOption("Toyota-Cars", "Avalon", "Avalon");
addOption("Toyota-Cars", "Camry", "Camry");
addOption("Toyota-Cars", "Celica", "Celica");
addOption("Toyota-Cars", "Corolla", "Corolla");
addOption("Toyota-Cars", "ECHO", "ECHO");

addOption("Toyota-SUVs/Van", "Select a model", "");
addOption("Toyota-SUVs/Van", "4Runner", "4Runner");
addOption("Toyota-SUVs/Van", "Highlander", "Highlander");
addOption("Toyota-SUVs/Van", "Land Cruiser", "Land Cruiser");
addOption("Toyota-SUVs/Van", "RAV4", "RAV4");

addOption("Toyota-Trucks", "Select a model", "");
addOption("Toyota-Trucks", "Tacoma", "Tacoma");
addOption("Toyota-Trucks", "Tundra", "Tundra", 1);

addOption("Honda", "Select vehicle type", "", "", 1); //Empty starter option
addList("Honda", "Cars", "car", "Honda-Cars");
addList("Honda", "SUVs/Van", "suv", "Honda-SUVs/Van");

addOption("Honda-Cars", "Select a model", "");
addOption("Honda-Cars", "Accord Sedan", "Accord Sedan");
addOption("Honda-Cars", "Accord Coupe", "Accord Coupe");
addOption("Honda-Cars", "Civic Sedan", "Civic Sedan");
addOption("Honda-Cars", "Civic Coupe", "Civic Coupe");
addOption("Honda-Cars", "Civic Hybrid", "Civic Hybrid");

addOption("Honda-SUVs/Van", "Select a model", "");
addOption("Honda-SUVs/Van", "CR-V", "CR-V");
addOption("Honda-SUVs/Van", "Pilot", "Pilot");
addOption("Honda-SUVs/Van", "Odyssey", "Odyssey", 1);

addOption("Chrysler", "Select vehicle type", "", "", 1); //Empty starter option
addList("Chrysler", "Cars", "car", "Chrysler-Cars");
addList("Chrysler", "SUVs/Van", "suv", "Chrysler-SUVs/Van");

addOption("Chrysler-Cars", "Select a model", "");
addOption("Chrysler-Cars", "300M", "300M");
addOption("Chrysler-Cars", "PT Cruiser", "PT Cruiser", 1);
addOption("Chrysler-Cars", "Concorde", "Concorde");
addOption("Chrysler-Cars", "Sebring Coupe", "Sebring Coupe");

addOption("Chrysler-SUVs/Van", "Select a model", "");
addOption("Chrysler-SUVs/Van", "Town & Country", "Town & Country");
addOption("Chrysler-SUVs/Van", "Voyager", "Voyager");

Here is another script that does this for you to the 4th level. The output at the moment is an alert() which shows what you have selected. You will need to change the output method to meet your own needs.

[HIGHLIGHT=“”]
<!doctype HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”>
<html>

<head>

<meta http-equiv=“Content-Type” content=“text/html; charset=windows-1252”>
<title>Select Products 4 Levels</title>
<script type=“text/javascript”>
<!–
// initialise shortcuts on page load
var selectObj1=null, selectObj2=null, selectObj3=null, selectObj4=null; // global
function init()
{ selectObj1=document.getElementById(“select_1”);
selectObj2=document.getElementById(“select_2”);
selectObj2.disabled=true;
//
selectObj3=document.getElementById(“select_3”);
selectObj3.disabled=true;
//
selectObj4=document.getElementById(“select_4”);
selectObj4.disabled=true;
}
// ========== end init() ==============
// second select box options list
var A= new Array()
A[“remote_1”]=[“Select here …”,“TV-1”,“DVD-1”];
A[“remote_2”]=[“Select here …”,“VCR-1”,“DVD-2”];
//
// third select box options list
var B= new Array()
B[“TV-1”]=[“Select here …”,“Sony”,“Sanyo”];
B[“DVD-1”]=[“Select here …”,“Honda”,“Ford”, “GMH”];
B[“VCR-1”]=[“Select here …”,“Red”,“Green”,“Blue”];
B[“DVD-2”]=[“Select here …”,“Panasonic”,“Daewoo”];
//
// 4th select box options list
var C= new Array()
C[“Sony”]=[“Select here …”,“Bob”,“Jane”];
C[“Sanyo”]=[“Select here …”,“Jill”,“Fred”, “George”];
C[“Honda”]=[“Select here …”,“Bill”,“Bruce”,“Peter”];
C[“GMH”]=[“Select here …”,“Kevin”,“Vanessa”];
C[“Red”]=[“Select here …”,“Helen”,“Larry”];
C[“Green”]=[“Select here …”,“Dave”,“Lucy”];
C[“Blue”]=[“Select here …”,“Tina”,“Jake”];
C[“Panasonic”]=[“Select here …”,“Edward”,“Amanda”];
C[“Daewoo”]=[“Select here …”,“Christine”,“Rosyln”];
//
// global variables
var saveObj=null, indx=null, targetObj=null, selectNo=null;
//
function process(obj,sNumb)
{ // disable unused select boxes
if(sNumb==2)
{ selectObj2.selectedIndex=“0”;
selectObj2.disabled=true;
selectObj3.selectedIndex=“0”;
selectObj3.disabled=true;
}
else if( sNumb==3)
{ selectObj3.selectedIndex=“0”;
selectObj3.disabled=true;
}
//
// store selected index
indx=obj.options.selectedIndex;
// invalid selection
if(indx==0){ return; }
// ---------
// save passed parameters for use after timeout deleay
saveObj=obj, selectNo=sNumb;
// put object items list into next select box after clearing
targetObj=document.getElementById(“select_”+selectNo)
targetObj.disabled=false;
// clear any existing options note that this starts from end of list, not beginning
for(var i=targetObj.options.length-1;i>-1;i–)
{ targetObj.options[i]=null; }
// build in short delay here to avoid error in Opera browser
setTimeout(“finishOff()”,50)
}
// ----------- 50ms delay here --------
// called from timeout in function process()
function finishOff()
{ var obj=saveObj; // from global
// fill selectObj options
var i, thisItem=0;
// build options list
switch(selectNo){
case 2 : targArray = A[obj.options[indx].value]; break;
case 3 : targArray = B[obj.options[indx].value]; break;
case 4 : targArray = C[obj.options[indx].value]; break;
}
//
for(i=0;i<targArray.length;i++)
{ thisItem=targArray[i];
// syntax is new Option(“text”, “value”, isDefaultSelectedFlag, isSelectedFlag)

       targetObj.options[i]=new Option(thisItem,thisItem,false,false);    
     } 
 obj.blur(); 

}
// ============ end process() ===================
// fires on selecting in third select box
function finish()
{ alert(“You have selected [”+selectObj1.value+“] [”+selectObj2.value+“] [”+selectObj3.value+“] [”+selectObj4.value+“]”)
}
// ------------
//
window.onload=init;
//–>
</script>
<style type=“text/css”>
<!–
.S_any { position:absolute; top:50px; width:100px; text-align:left; }
#S1 { left:10px; }
#S2 { left:150px; }
#S3 { left:300px; }
#S4 { left:450px; }
select { width:120px; }
–>
</style>
</head>

<body>

<div id=“S1” class=“S_any”>
<select id=“select_1” onchange=“process(this,2)”>
<option value=“0”>Select here …</option>
<option value=“remote_1”>Remote 1</option>
<option value=“remote_2”>Remote 2</option>
</select>
</div>
<!-- end S1 –>
<div id=“S2” class=“S_any”>
<select id=“select_2” onchange=“process(this,3)”>
<option value=“0”>Select here …</option>
</select></div>
<!- end S2>
<div id=“S3” class=“S_any”>
<select id=“select_3” onchange=“process(this,4)”>
<option value=“0”>Select here …</option>
</select></div>
<!-- end S3 –>
<div id=“S4” class=“S_any”>
<select id=“select_4” onchange=“finish()”>
<option value=“0”>Select here …</option>
</select></div>
<!-- end S4 –>

</body>

</html>

cool thanks for the code :slight_smile: