花了半天时间实现一个多级联动下拉框,目的是对某一植物进行“门纲目科属”的归类。使用的技术是javascript+xml,之所以不用数据库,一来这方面的数据虽然量大但都是固定不变的,二来不希望加重服务器的负担,第三是因为这种多级从属关系的数据不太适合放在数据库里。
//载入xml文件 var xmlDoc=new ActiveXObject("Microsoft.XMLDOM"); xmlDoc.async = false; xmlDoc.load("classify.xml"); var currentNode;//当前所在节点 //读取xml文件数据并设置门、纲、目、科、属的下拉框 //设置“门”的下拉框 function setPhylum(){ currentNode=xmlDoc.documentElement; var phylums = currentNode.childNodes; for(var i=0;i<phylums.length;i++){ //从门到属,都有name属性标签,并且所有下拉框选项索引都是从1开始 var phylumName=phylums(i).selectNodes("name")(0).text; document.forms[0].phylum.options[i+1]=new Option(phylumName,phylumName); } } //设置“纲”的下拉框 function setClazz(selectedIndex){ //取消下拉框的禁用 //后面的下拉框禁用,这是因应各下拉框的无序选择可能产生的错误 //比如选了“科”又回头重新选“目”,或更改同一个下拉框选项) document.forms[0].clazz.disabled=null; document.forms[0].order.disabled="disabled"; document.forms[0].family.disabled="disabled"; document.forms[0].genus.disabled="disabled"; //将选中的门节点作为当前节点,注意这里需要将索引回减1 //因为门的父节点没有name属性标签,而下拉框的索引又是从1开始 //currentNode的赋值应使用绝对定位,也是因应各下拉框的无序选择 //currentNode=currentNode.childNodes(selectedIndex-1); currentNode=xmlDoc.documentElement.childNodes(selectedIndex-1); var clazzes=currentNode.childNodes; clearOption(document.forms[0].clazz); //因为门节点的第一个子节点为name属性标签,故循环时索引从1开始 //相应的下拉框的索引就与纲节点的索引同步(不需要options[i+1]),目、科、属也是一样 for(var i=1;i<clazzes.length;i++){ var clazzName=clazzes(i).selectNodes("name")(0).text; document.forms[0].clazz.options[i]=new Option(clazzName,clazzName); } } //设置“目”的下拉框 function setOrder(selectedIndex){ //取消下拉框的禁用 //后面的下拉框禁用,这是因应各下拉框的无序选择可能产生的错误(比如选了“科”又回头重新选“目”) document.forms[0].order.disabled=null; document.forms[0].family.disabled="disabled"; document.forms[0].genus.disabled="disabled"; //currentNode的赋值应使用绝对定位 var phylumSI=document.forms[0].phylum.selectedIndex; //phylum selected index currentNode=xmlDoc.documentElement .childNodes(phylumSI-1) .childNodes(selectedIndex); var orders=currentNode.childNodes; clearOption(document.forms[0].order); for(var i=1;i<orders.length;i++){ var orderName=orders(i).selectNodes("name")(0).text; document.forms[0].order.options[i]=new Option(orderName,orderName); } } //设置“科”的下拉框 function setFamily(selectedIndex){ document.forms[0].family.disabled=null;//取消下拉框的禁用 document.forms[0].genus.disabled="disabled";//后面的下拉框禁用 //currentNode的赋值应使用绝对定位 var phylumSI=document.forms[0].phylum.selectedIndex;//phylum selected index var clazzSI=document.forms[0].clazz.selectedIndex; //clazz selected index currentNode=xmlDoc.documentElement .childNodes(phylumSI-1) .childNodes(clazzSI) .childNodes(selectedIndex); var families=currentNode.childNodes; clearOption(document.forms[0].family); for(var i=1;i<families.length;i++){ var familyName=families(i).selectNodes("name")(0).text; document.forms[0].family.options[i]=new Option(familyName,familyName); } } //设置“属”的下拉框 function setGenus(selectedIndex){ document.forms[0].genus.disabled=null;//取消下拉框的禁用 //currentNode的赋值应使用绝对定位 var phylumSI=document.forms[0].phylum.selectedIndex;//phylum selected index var clazzSI=document.forms[0].clazz.selectedIndex; //clazz selected index var orderSI=document.forms[0].order.selectedIndex; //order selected index currentNode=xmlDoc.documentElement .childNodes(phylumSI-1) .childNodes(clazzSI) .childNodes(orderSI) .childNodes(selectedIndex); var genuses=currentNode.childNodes; clearOption(document.forms[0].genus); for(var i=1;i<genuses.length;i++){ //属为叶节点 var genusName=genuses(i).text; document.forms[0].genus.options[i]=new Option(genusName,genusName); } } //清空下拉框选项 function clearOption(selectElement){ for(var i=1;i<selectElement.options.length;i++){ selectElement.options[i]=null; } }
<form id="plantForm" action="plant" method="post"> <select id="phylum" name="plantForm.phylum" onchange="setClazz(this.selectedIndex)"> <option selected="selected">———门———</option> </select> <select id="clazz" name="plantForm.clazz" disabled="disabled" onchange="setOrder(this.selectedIndex)"> <option selected="selected">———纲———</option> </select> <select id="order" name="plantForm.order" disabled="disabled" onchange="setFamily(this.selectedIndex)"> <option selected="selected">———目———</option> </select> <select id="family" name="plantForm.family" disabled="disabled" onchange="setGenus(this.selectedIndex)"> <option selected="selected">———科———</option> </select> <select id="genus" name="plantForm.genus" disabled="disabled"> <option selected="selected">———属———</option> </select> </form> <script type="text/javascript"> setPhylum();//设置第一个下拉框 </script>
<?xml version="1.0" encoding="UTF-8"?> <plant> <phylum> <name>被子植物门</name> <clazz> <name>双子叶植物纲</name> <order> <name>菊目</name> <family> <name>菊科</name> <genus>菊属</genus> </family> <family> <name>桔梗科</name> <genus>同钟花属</genus> <genus>刺萼参属</genus> </family> </order> <order> <name>胡椒目</name> <family> <name>胡椒科</name> <genus>胡椒属</genus> <genus>草胡椒属</genus> <genus>齐头绒属</genus> </family> </order> </clazz> </phylum> <phylum> <name>蕨类植物门</name> <clazz> <name>石松纲</name> <order> <name>石松目</name> <family> <name>石松科</name> <genus>石松属</genus> </family> </order> </clazz> </phylum> </plant>
可以实现上下级下拉框的联动,支持无序选择,若向上重新选择,下下层下拉框将自动被禁用,下层下拉框选项也会相应改变。
|
|