| | |
AJAX dropdown list
Please support our JavaScript / DHTML / AJAX advertiser: PostgreSQL or MySQL? Compare and contrast the two most popular open source databases
![]() |
•
•
Join Date: Jul 2009
Posts: 15
Reputation:
Solved Threads: 0
Hi Airshow
Here's the code as it stands now. I've reverted to the version that works in FF. Thanks for your time again.
HTML form
.js
Sample PHP file
Here's the code as it stands now. I've reverted to the version that works in FF. Thanks for your time again.
HTML form
JavaScript / DHTML / AJAX Syntax (Toggle Plain Text)
<html> <head> <script type = text/javascript src = getschool1.js></script> <link rel="stylesheet" type="text/css" href="form.css"> </head> <body> <form id = 'prices' action="process.php" method="post"> <table> <td align="right">Language of interest:</td> <td> <select id="language" name="language" onChange="getSchool1(this.value)"> <option value="none selected"> --- select --- </option> <option value="french">French</option> <option value="german">German</option> <option value="italian">Italian</option> <option value="spanish">Spanish</option> <option value="russian">Russian</option> </select> </td> <tr> <td align="right">School</td> <td> <select id="school" name ="school" onChange="getAge(this.value)"disabled> <option value="none selected">Select Language First</option> </select> </td> </tr> <tr> <td align="right">Course Type</td> <td> <select id = "age" name="age" onChange="getLevel(this.value)" disabled> <option value="none selected"> Select School First </option> </select> </td> </tr> <tr> <td align="right">Class Type</td> <td> <select id="level" name="level" onChange="getDuration(this.value)" disabled> <option value="none selected">Select Course Type First</option> </select> </td> </tr> <tr> <td align="right">Duration</td> <td> <select id="duration" name="duration" onChange="getPlace(this.value)" disabled> <option value="none selected">Select Class Type First</option> </select> </td> </tr> <tr> <td align="right">Accommodation</td> <td> <select id ="place" name ="place" onChange = "getBoard(this.value)" disabled> <option value="none selected">Select Duration First</option> </tr> <tr> <td align="right">Board</td> <td> <select id ="board" name="board" onChange = "getRoom(this.value)" disabled> <option value="none selected">Select Acc First</option> </tr> <td align="right">Room Type</td> <td> <select id ="room" name="room" onChange = "getSeason(this.value)" disabled> <option value="none selected">Select Board First</option> </tr> <tr> <td align="right">Season</td> <td> <select id ="season" name="season" disabled> <option value="none selected">Select Room First</option> </tr> </br> <td align="right">Currency</td> <td> <select name="currency" > <option value="none selected"> --- select --- </option> <option value="euro">Euro</option> <option value="sterling">Sterling</option> <option value="dollar">Dollar</option> </tr> <tr> <td> <input type="submit" id="submit" name="submit" value="Submit" /> <input type="hidden" name="submitted" id="submitted" value="true" /> </tr> </td> </table>
.js
JavaScript / DHTML / AJAX Syntax (Toggle Plain Text)
function GetXmlHttpObject(){ var xmlHttp = false; try{ xmlHttp = new ActiveXObject("Msxml2.XMLHTTP")//For Old Microsoft Browsers } catch(e){ try{ xmlHttp = new ActiveXObject("Microsoft.XMLHTTP")//For Microsoft IE 6.0+ } catch(e2){ xmlHttp = false; } } if (!xmlHttp && typeof XMLHttpRequest != 'undefined') { xmlHttp = new XMLHttpRequest();//For Mozilla, Opera Browsers } if(!xmlHttp) { alert("Browser does not support HTTP Request"); } return xmlHttp; } function getSchool1(langID){ var xmlhttp = GetXmlHttpObject(); if(!xmlhttp){ return; } var url = "findcity.php" + "?language=" + langID + "&sid=" + Math.random(); xmlhttp.onreadystatechange = function(){ if(xmlhttp.readyState == 4){ document.getElementById("school").innerHTML = xmlhttp.responseText; document.getElementById("school").disabled = 0; } }; xmlhttp.open("GET",url,true); xmlhttp.send(null); } function getAge(school){ var xmlhttp = GetXmlHttpObject(); if(!xmlhttp){ return; } var langID = document.getElementById("language").value; //var school = document.getElementById("school").value; var url = "findage.php" + "?language=" + langID + "&school="+ school + "&sid=" + Math.random(); xmlhttp.onreadystatechange = function(){ if(xmlhttp.readyState == 4){ document.getElementById("age").innerHTML = xmlhttp.responseText; document.getElementById("age").disabled = 0; } }; xmlhttp.open("GET",url,true); xmlhttp.send(null); } function getLevel(age){ var xmlhttp = GetXmlHttpObject(); if(!xmlhttp){ return; } var langID = document.getElementById("language").value; var schoolID = document.getElementById("school").value; var url = "findlevel.php" + "?language=" + langID + "&school="+ schoolID + "&age="+ age + "&sid=" + Math.random(); alert(url); xmlhttp.onreadystatechange = function(){ if (xmlhttp.readyState == 4){ document.getElementById("level").innerHTML = xmlhttp.responseText; document.getElementById("level").disabled = 0; } }; xmlhttp.open("GET",url,true); xmlhttp.send(null); } function getDuration(level){ var xmlhttp = GetXmlHttpObject(); if(!xmlhttp){ return; } var langID = document.getElementById("language").value; var schoolID = document.getElementById("school").value; var ageID = document.getElementById("age").value; var url = "getduration.php" + "?language=" + langID + "&school=" + schoolID + "&age="+ ageID + "&level=" + level + "&sid=" + Math.random(); alert(url); xmlhttp.onreadystatechange = function(){ if (xmlhttp.readyState == 4){ // document.getElementById("durationdiv").innerHTML = xmlhttp.responseText; document.getElementById("duration").innerHTML = xmlhttp.responseText; document.getElementById("duration").disabled = 0; alert(xmlhttp.responseText); } }; xmlhttp.open("GET",url,true); xmlhttp.send(null); } function getPlace(duration){ var xmlhttp = GetXmlHttpObject(); if(!xmlhttp){ return; } var langID = document.getElementById("language").value; var schoolID = document.getElementById("school").value; var ageID = document.getElementById("age").value; var levelID = document.getElementById("level").value; var url = "findplace.php" + "?language=" + langID + "&school=" + schoolID + "&age="+ ageID + "&level=" + levelID + "&duration=" + duration + "&sid=" + Math.random(); xmlhttp.onreadystatechange = function(){ if (xmlhttp.readyState == 4){ // document.getElementById("durationdiv").innerHTML = xmlhttp.responseText; document.getElementById("place").innerHTML = xmlhttp.responseText; document.getElementById("place").disabled = 0; } }; xmlhttp.open("GET",url,true); xmlhttp.send(null); } function getBoard(place){ var xmlhttp = GetXmlHttpObject(); if(!xmlhttp){ return; } var langID = document.getElementById("language").value; var schoolID = document.getElementById("school").value; var ageID = document.getElementById("age").value; var levelID = document.getElementById("level").value; var durationID = document.getElementById("duration").value; var url = "findboard.php" + "?language=" + langID + "&school=" + schoolID + "&age="+ ageID + "&level=" + levelID + "&duration=" + durationID + "&place=" + place + "&sid=" + Math.random(); xmlhttp.onreadystatechange = function(){ if (xmlhttp.readyState == 4){ // document.getElementById("durationdiv").innerHTML = xmlhttp.responseText; document.getElementById("board").innerHTML = xmlhttp.responseText; document.getElementById("board").disabled = 0; } }; xmlhttp.open("GET",url,true); xmlhttp.send(null); } function getRoom(board){ var xmlhttp = GetXmlHttpObject(); if(!xmlhttp){ return; } var langID = document.getElementById("language").value; var schoolID = document.getElementById("school").value; var ageID = document.getElementById("age").value; var levelID = document.getElementById("level").value; var durationID = document.getElementById("duration").value; var placeID = document.getElementById("place").value; var url = "findroom.php" + "?language=" + langID + "&school=" + schoolID + "&age="+ ageID + "&level=" + levelID + "&duration=" + durationID + "&place=" + placeID + "&board=" + board + "&sid=" + Math.random(); xmlhttp.onreadystatechange = function(){ if (xmlhttp.readyState == 4){ // document.getElementById("durationdiv").innerHTML = xmlhttp.responseText; document.getElementById("room").innerHTML = xmlhttp.responseText; document.getElementById("room").disabled = 0; } }; xmlhttp.open("GET",url,true); xmlhttp.send(null); } function getSeason(room){ var xmlhttp = GetXmlHttpObject(); if(!xmlhttp){ return; } var langID = document.getElementById("language").value; var schoolID = document.getElementById("school").value; var ageID = document.getElementById("age").value; var levelID = document.getElementById("level").value; var durationID = document.getElementById("duration").value; var placeID = document.getElementById("place").value; var boardID = document.getElementById("board").value; var url = "findseason.php" + "?language=" + langID + "&school=" + schoolID + "&age="+ ageID + "&level=" + levelID + "&duration=" + durationID + "&place=" + placeID + "&board=" + boardID + "&room=" + room + "&sid=" + Math.random(); xmlhttp.onreadystatechange = function(){ if (xmlhttp.readyState == 4){ // document.getElementById("durationdiv").innerHTML = xmlhttp.responseText; document.getElementById("season").innerHTML = xmlhttp.responseText; document.getElementById("season").disabled = 0; } }; xmlhttp.open("GET",url,true); xmlhttp.send(null); }
Sample PHP file
JavaScript / DHTML / AJAX Syntax (Toggle Plain Text)
<?php $language = $_GET["language"]; $school = $_GET["school"]; $age = $_GET["age"]; mysql_connect("localhost", "root", "filabo01") or die(mysql_error()); mysql_select_db("burkes1_jos") or die(mysql_error()); $query = mysql_query("SELECT le.leveltype FROM ssa_level AS le, ssa_schoolid AS s, ssa_course AS c, ssa_age as ag WHERE s.school = '$school' AND ag.agetype = '$age' AND s.schoolid = c.schoolid AND ag.ageid = c.ageid AND le.levelid = c.levelid GROUP BY le.leveltype") or die (mysql_error()); ?> <option>Select Class Type</option> <? while($row = mysql_fetch_array($query)) { ?> <option value = <?=$row['leveltype']?>><?=$row['leveltype']?></option> <? } ?>
Daved,
I must get to work now but had a quick look
Nothing jumps out as being particularly wrong for IE but you might like to try replacing :
with
which is generally safer.
Apart from that, the Javascript will simplify enormously (once it's debugged). Reason being, eight of your nine functions are virtually identical and can be replaced with a single function, branching for (a) which php script is called and (b) where the reponse is stuffed. I can show how to do this efficiently.
Will look further when I return home later.
Airshow
I must get to work now but had a quick look
Nothing jumps out as being particularly wrong for IE but you might like to try replacing :
JavaScript / DHTML / AJAX Syntax (Toggle Plain Text)
document.getElementById("room").disabled = 0;
JavaScript / DHTML / AJAX Syntax (Toggle Plain Text)
document.getElementById("room").setAttribute('disabled', 0);
Apart from that, the Javascript will simplify enormously (once it's debugged). Reason being, eight of your nine functions are virtually identical and can be replaced with a single function, branching for (a) which php script is called and (b) where the reponse is stuffed. I can show how to do this efficiently.
Will look further when I return home later.
Airshow
50% of the solution lies in accurately describing the problem!
Daved83,
It turns out that IE has a bug whereby "if you use innerHTML to add or update form elements, all sorts of screwiness can occur".
The linked article suggests a workaround which proves to be a little impractical for your purpose so I have formulated something that still involves innerHTML but at one container higher than your select menus.
*** *** *** *** *** *** ***
My workaround (see attached file) requires your php scripts each to return a WHOLE select menu complete with the
*** *** *** *** *** *** ***
There's a second (logical) issue, in that the user may go back, higher in the cascade, and re-select from a menu. This will invalidate all subordinate menus in the cascade so we must always ensure that all subordinate menus from "x+2" are
reset to "null" settings. This is moderately tricky but the code below includes code to cater for it, involving stashing away a clone of the originally served "Select xxxx first" menu, then re-cloning when required back into its original place in the DOM (see comments in code) - hopefully not as inefficient as it may seem as javascript's "garbage collection" should handle the debris on each occasion. Besides, the page is short-lived so we are not too worried.
I have tested in IE6, FF 3.5.2 and Opera 9.0.1
The big test will be FORM SUBMISSION!!! There's still a possibility that IE may not include all menu values in the POST. I have not been able to test this aspect.
Airshow
It turns out that IE has a bug whereby "if you use innerHTML to add or update form elements, all sorts of screwiness can occur".
The linked article suggests a workaround which proves to be a little impractical for your purpose so I have formulated something that still involves innerHTML but at one container higher than your select menus.
*** *** *** *** *** *** ***
My workaround (see attached file) requires your php scripts each to return a WHOLE select menu complete with the
<select ....></select> tags (including all attributes, id , name , onchange - but not disabled ). *** *** *** *** *** *** ***
There's a second (logical) issue, in that the user may go back, higher in the cascade, and re-select from a menu. This will invalidate all subordinate menus in the cascade so we must always ensure that all subordinate menus from "x+2" are
reset to "null" settings. This is moderately tricky but the code below includes code to cater for it, involving stashing away a clone of the originally served "Select xxxx first" menu, then re-cloning when required back into its original place in the DOM (see comments in code) - hopefully not as inefficient as it may seem as javascript's "garbage collection" should handle the debris on each occasion. Besides, the page is short-lived so we are not too worried.
HTML Syntax (Toggle Plain Text)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head> <title>Airshow :: Untitled</title> <!-- daniweb_post959826.html --> <link rel="stylesheet" type="text/css" href="form.css"> <script type = text/javascript src = getschool1.js></script> <script> function GetXmlHttpObject(){ var xmlHttp = false; try { xmlHttp = new ActiveXObject("Msxml2.XMLHTTP") //For Old Microsoft Browsers } catch(e){ try{ xmlHttp = new ActiveXObject("Microsoft.XMLHTTP")//For Microsoft IE 6.0+ } catch(e2){ xmlHttp = false; } } if (!xmlHttp && typeof XMLHttpRequest != 'undefined'){ xmlHttp = new XMLHttpRequest();//For Mozilla, Opera Browsers } if(!xmlHttp) { alert("Browser does not support HTTP Request"); } return xmlHttp; } //********************************************************************* function getNextMenu(x){ var xmlhttp = GetXmlHttpObject(); if(!xmlhttp){ return; } var menus = [ [ 'language' , 'findcity.php' ], [ 'school' , 'findage.php' ], [ 'age' , 'findlevel.php' ], [ 'level' , 'findduration.php' ], [ 'duration' , 'findplace.php' ], [ 'place' , 'findboard.php' ], [ 'board' , 'findroom.php' ], [ 'room' , 'findseason.php' ], [ 'season' , '' ] ]; //1. Compose url - we can now do this by looping through the menus array. var queryString = []; for(var i=0; i<menus.length; i++){ var menu = document.getElementById(menus[i][0]); if(menu && !menu.getAttribute('disabled')){ queryString.push(menu.name + '=' + menu[menu.selectedIndex].value); } } url = menus[x][1] + '?' + queryString.join('&'); //2. Establish AJAX response handler xmlhttp.onreadystatechange = function(){ var menu, menuContainer, cloned; if (xmlhttp.readyState == 4){ //2a. Set options for next menu in the cascade. menu = document.getElementById(menus[x+1][0]); if(menu){ menuContainer = menu.parentNode; if(!menuContainer.getAttribute('cloned')){ menuContainer.nullClone = menu.cloneNode(true);//clone the "null" menu and stash it away (invisibly) as an attribute of the menu's container. menuContainer.setAttribute('cloned', 1); } menuContainer.innerHTML = xmlhttp.responseText; } //2b. User may go back, higher in the cascade, and se-select from a menu. // This will invalidate all subordinate menus in the cascade. // Therefore reset all subordinate menus to "null" settings. for(var i=x+2; i<menus.length; i++){ menu = document.getElementById(menus[i][0]); if(menu){ menuContainer = menu.parentNode; if(menuContainer && menuContainer.getAttribute('cloned')){ menuContainer.replaceChild(menuContainer.nullClone.cloneNode(true), menu); } } } } }; xmlhttp.open("GET",url,true); xmlhttp.send(null); } </script> </head> <body> <form id='prices' action="process.php" method="post"> <table> <td align="right"> Language of interest:</td> <td> <select id="language" name="language" onChange="getNextMenu(0)"> <option value="none selected"> --- select --- </option> <option value="french"> French</option> <option value="german"> German</option> <option value="italian"> Italian</option> <option value="spanish"> Spanish</option> <option value="russian"> Russian</option> </select> </td> <tr> <td align="right"> School</td> <td> <select id="school" name="school" onChange="getNextMenu(1)" disabled> <option value="none selected"> Select Language First</option> </select> </td> </tr> <tr> <td align="right"> Course Type</td> <td> <select id="age" name="age" onChange="getNextMenu(2)" disabled> <option value="none selected"> Select School First </option> </select> </td> </tr> <tr> <td align="right"> Class Type</td> <td> <select id="level" name="level" onChange="getNextMenu(3)" disabled> <option value="none selected"> Select Course Type First</option> </select> </td> </tr> <tr> <td align="right"> Duration</td> <td> <select id="duration" name="duration" onChange="getNextMenu(4)" disabled> <option value="none selected"> Select Class Type First</option> </select> </td> </tr> <tr> <td align="right"> Accommodation</td> <td> <select id="place" name="place" onChange="getNextMenu(5)" disabled> <option value="none selected"> Select Duration First</option> </select> </td> </tr> <tr> <td align="right"> Board</td> <td> <select id="board" name="board" onChange="getNextMenu(6)" disabled> <option value="none selected"> Select Acc First</option> </select> </td> </tr> <tr> <td align="right"> Room Type</td> <td> <select id="room" name="room" onChange="getNextMenu(7)" disabled> <option value="none selected"> Select Board First</option> </select> </tr> <tr> <td align="right"> Season</td> <td> <select id="season" name="season" disabled> <option value="none selected"> Select Room First</option> </select> </td> </tr> <tr> <td align="right"> Currency</td> <td> <select name="currency" > <option value="none selected"> --- select --- </option> <option value="euro"> Euro</option> <option value="sterling"> Sterling</option> <option value="dollar"> Dollar</option> </select> </td> </tr> <tr> <td> <input type="submit" id="submit" name="submit" value="Submit" /> <input type="hidden" name="submitted" id="submitted" value="true" /> </td> </tr> </td> </table> </body> </html>
I have tested in IE6, FF 3.5.2 and Opera 9.0.1
The big test will be FORM SUBMISSION!!! There's still a possibility that IE may not include all menu values in the POST. I have not been able to test this aspect.
Airshow
Last edited by Airshow; Aug 27th, 2009 at 9:36 pm.
50% of the solution lies in accurately describing the problem!
That's great Daved.
I've just thought of something you might like to watch out for. ....
.... In browsers, the user can give focus to a select menu then use the keyboard's up/down arrow keys to run through the options. In IE the onchange event fires as each option is selected (in FF and Opera I think the user needs to hit enter or return). Thus, in your application IE could initiate several Ajax calls before any of them has responded. Because these calls are asynchronous, the server could respond in any order and the x+1th menu in the cascade cound wind up showing the wrong set of options. Maybe you could run some tests to see if it's an issue.
A solution would be to disable the current (xth) menu in
Another approach would be for the response handler to force the xth menu to show the right option for the response. Thus, the last response to arrive will win the day.
Either (or both) of these will make it pretty safe and should be fairly simple additions to the code but please ask if you need help.
Airshow
I've just thought of something you might like to watch out for. ....
.... In browsers, the user can give focus to a select menu then use the keyboard's up/down arrow keys to run through the options. In IE the onchange event fires as each option is selected (in FF and Opera I think the user needs to hit enter or return). Thus, in your application IE could initiate several Ajax calls before any of them has responded. Because these calls are asynchronous, the server could respond in any order and the x+1th menu in the cascade cound wind up showing the wrong set of options. Maybe you could run some tests to see if it's an issue.
A solution would be to disable the current (xth) menu in
getNextMenu() , (eg. at the bottom of the querystring composition loop) then re-enable it in the onreadystatechange response handler. (In fact it might be a good idea to disable the whole cascade).Another approach would be for the response handler to force the xth menu to show the right option for the response. Thus, the last response to arrive will win the day.
Either (or both) of these will make it pretty safe and should be fairly simple additions to the code but please ask if you need help.
Airshow
50% of the solution lies in accurately describing the problem!
![]() |
Similar Threads
- Cascading Dropdown list with (AJAX, PHP) (PHP)
- AJAX dropdown + PHP + MySQL (JavaScript / DHTML / AJAX)
- Dropdown list Last value (ASP.NET)
- DropDown List (VB.NET)
- Feeding a value in a dropdown list to another dropdown list (PHP)
Other Threads in the JavaScript / DHTML / AJAX Forum
- Previous Thread: JavaScript works in MSIE but not FireFox
- Next Thread: javascript help pls
Views: 1415 | Replies: 15
| Thread Tools | Search this Thread |
Tag cloud for JavaScript / DHTML / AJAX
ajax ajaxexample ajaxjspservlets array autoplay blackjack browser captchaformproblem checkbox child class close codes date debugger dependent developer disablefirebug dom editor element embed engine events explorer ext file flash form forms game gears getselection google gxt hiddenvalue highlightedword hint html ie7 ie8 iframe internet java javascript javascripthelp2020 jquery jsf jsfile jsp jump libcurl maps margin marquee masterpage math matrixcaptcha media mysql object onerror onmouseoutdivproblem onreadystatechange parent passing paypal pdf php player position post programming rated redirect runtime safari scriptlets scroll search security session shopping size software solutions sources star stars stretch synchronous tweet unicode variables web webkit webservice window wysiwyg \n





