PDA

View Full Version : dynamic connected dropdowns to a nestinglevel of your choice


Roelf
02-25-2003, 02:13 PM
Hi,

finally i created something which i think is useful, so i am going to post it here. I see a lot of questions about connecting dropdown elements together, where the options in the second dd are depending on the selection in the first. People even want to connect three of them together. My thinkin was, why not make it as flexible as possible. Imagine a hierarchy of choices, where neither branche of the hierarchy is as deep as another one. I want to make a dd with variable levels so a dd contains all the children of a certain level of the hierarchy. After a selection is made, the script checks if the hierarchy has children in the next level. When a selection is altered, the deeper dd's are removed and created again with the proper options.

All is based on a xml-file which holds the dropdowndata and a function in a html-file to read it and create the drop downs where they are needed

Points to improve:
- make it x-browser compatible (currently tested in IE5.5)
- perhaps the inputfile (xml) should be changed so the name and (if added) the value, or the caption shouldn't be attributes of an element, but a child-element
- code efficiency
- get the maxdepth variable dynamically, by analyzing the contents of the xml before processing
- create positions to put the captions and the dd's dynamically, based on the xml-data instead of fixing them in the html file
- make the xml more strict, add a dtd or something like that
- lay-out aspects
- whatever you can think of

I am not an xml-expert, neither am i a javascript expert. I managed to create this, it works the way i intended, i leave it up to you guys to improve it....
Improved versions will be used by me ofcourse :D


Roelf
file: dropdowndata.xml

<ddlevel0 name="geo" caption="Select a continent">
<ddlevel1 name="North America" caption="Select a country">
<ddlevel2 name="United States" caption="Select a state">
<ddlevel3 name="Arkansas" caption="Select a city">
<ddlevel4 name="City 1 in arkansas" />
<ddlevel4 name="City 2 in arkansas" />
<ddlevel4 name="City 3 in arkansas" caption="Perhaps you want to select a street">
<ddlevel5 name="Street1" />
<ddlevel5 name="Street2" />
<ddlevel5 name="Street3" />
</ddlevel4>
</ddlevel3>
<ddlevel3 name="Texas" caption="Select a city">
<ddlevel4 name="City 1 in Texas" />
<ddlevel4 name="City 2 in Texas" />
<ddlevel4 name="City 3 in Texas" />
</ddlevel3>
<ddlevel3 name="Another state" caption="Select a city">
<ddlevel4 name="City 1 in another state" />
<ddlevel4 name="City 2 in another state" />
<ddlevel4 name="City 3 in another state" />
<ddlevel4 name="City 4 in another state" />
<ddlevel4 name="City 5 in another state" />
<ddlevel4 name="City 6 in another state" />
</ddlevel3>
</ddlevel2>
<ddlevel2 name="Canada" caption="Select a city">
<ddlevel3 name="Montreal" />
<ddlevel3 name="Some city in Canada" />
<ddlevel3 name="Some other city" />
<ddlevel3 name="Yet another one in canada" />
</ddlevel2>
</ddlevel1>
<ddlevel1 name="Africa" caption="Select a county">
</ddlevel1>
<ddlevel1 name="Europe" caption="Select a country">
</ddlevel1>
<ddlevel1 name="Australia" caption="Select a city">
<ddlevel2 name="Sidney" />
<ddlevel2 name="Canberra" />
<ddlevel2 name="Another one in Australia" />
<ddlevel2 name="Aussie city" />
</ddlevel1>
</ddlevel0>


file: thehtml.html

<html>
<head>
<title>testdocument</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

<script type="text/javascript" language="JavaScript">
/*********************************************
* Dynamic connected dropdown menus Version 1.0
* Script created by Roelf Prakken
* email: r.prakken@home.nl
*********************************************/

xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async = false;
xmlDoc.load("dropdowndata.xml");
var maxlevel = 5;

function createdropdown (level, selectiontocreate) {
// first, delete all selects and captions from previously made selections in this hierarchy level
for (var d = level; d < maxlevel; d++) {
var caplocation = document.getElementById("caption" + d);
if (caplocation.childNodes.length > 1){
caplocation.removeChild(caplocation.childNodes[1]);
}
var ddlocation = document.getElementById("dd" + d);
if (ddlocation.childNodes.length > 1){
ddlocation.removeChild(ddlocation.childNodes[1]);
}
}

// now get the data for the new dropdown
var dd = xmlDoc.getElementsByTagName("ddlevel" + level)
var ddlength = dd.length
for (var i = 0; i < ddlength; i++) {
if (dd[i].getAttribute("name") == selectiontocreate) {
// the correct element is found
var numberofoptions = dd[i].childNodes.length;
if (numberofoptions > 0) {
// get the captiontext from the selected element
var capText = document.createTextNode(dd[i].getAttribute("caption"));

// create the dropdown with all the options
var selObj = document.createElement("select");

// first option is not a real option
selObj.options[0] = new Option(dd[i].getAttribute("caption"))
for (var j = 0; j < numberofoptions; j++){
selObj.options[selObj.options.length] = new Option(dd[i].childNodes[j].getAttribute("name"),
dd[i].childNodes[j].getAttribute("name"))
}

// add the eventhandler to the select, if the node has children
selObj.onchange = function () {
createdropdown((level + 1), this.options[this.selectedIndex].value);
}

// put the caption and the dropdown in the correct place
var caplocation = document.getElementById("caption" + level);
caplocation.appendChild(capText);
var ddlocation = document.getElementById("dd" + level);
ddlocation.appendChild(selObj);
}
}
}
}

</script>

</head>
<body onload="createdropdown(0, 'geo')">


<form name="dynamic">
<table border="1" width="50%">
<tr>
<td id="caption0">&nbsp;</td><td id="dd0">&nbsp;</td>
</tr>
<tr>
<td id="caption1">&nbsp;</td><td id="dd1">&nbsp;</td>
</tr>
<tr>
<td id="caption2">&nbsp;</td><td id="dd2">&nbsp;</td>
</tr>
<tr>
<td id="caption3">&nbsp;</td><td id="dd3">&nbsp;</td>
</tr>
<tr>
<td id="caption4">&nbsp;</td><td id="dd4">&nbsp;</td>
</tr>
</table>
</form>
</body>
</html>

beetle
02-25-2003, 07:16 PM
No online working demo? :eek:

Roelf
02-25-2003, 08:37 PM
hmmm, not yet, can't get the function to wait until the xml is completely loaded.....
have to do a little research for that

also, the comment lines in the script header are a little disturbed by the BB-software, if you copy and past into a file, delete the space between the / and the *, and put all the *'s back in one line

trying to get things done tomorrow, now's time for bed. If someone can point me into the right direction where to look for code which stalls script execution while waiting for the xml to load.........

thanks in ad... wait, thats not allowed anymore :D

found it
xmlDoc.async = false;

http://www22.brinkster.com/rprakken/experiments/dropdown.html

kwhubby
02-25-2003, 08:54 PM
thats cool! Its practically the first really useful xml+javascript thing ive seen.

neonwhiskey
03-07-2003, 11:50 PM
hi,
Does anyone have an example of XML being used to create a cascading menu (like the Start menu in Windows, with several levels).

Thx!
Jennifer

brothercake
03-18-2003, 09:52 AM
My demo menu at http://www.brothercake.com/dropdown/template_custom_xml.phtml is generated from XML; but the transformation takes place server-side, using XSLT to generate javacript within a PHP file. I'ts probably not what you wanted (since there's no client-side XML manipulation involved), but it's documented at http://www.brothercake.com/dropdown/dynamic.html#xml_custom if you're interested

kwhubby
03-18-2003, 08:55 PM
wow thats cool!!! I never knew you could do those image transform things on anything besides images!