Hi everyone. I'm brand new to Ajax so forgive me for the stupid question! I'm trying to populate a triple dropdown menu based on Roshans code The first dropdown populates the second one fine but when I clidk on the second it populates itself instead of the one below! I thought at first it was a simple problem with the element ID its not and I can't figure it out. Any ideas much appreciated.

Daved83,

It's very hard to know what might be going on in the absence of your code. It is quite acceptable on Daniweb to post it but please remember to wrap it in code-tags.

Personally, I would start by looking at the client-side code; the AJAX call and its response handler.

Airshow

Edited 3 Years Ago by mike_2000_17: Fixed formatting

Hi Airshow,

Thanks for the reply. My problem is that, although I can get the third dropdown to populate itself, I cannot seem to send the variable needed for the query. The first one works perfectly i.e the second dropdown populates itself based on user input in the first field. I think the problem is where the function is called from findcity.php or else the parameters in the function getLevel are wrong, I'm a bit of a novice so unsure. Sorry if I was unclear before here's some of my code. Thanks again for the help.

html form

<form action="process.php" method="post">
<table>
<td align="right">Language of interest:</td>
<td>
<select 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>
<tr>
<td align="right">Course Type</td>
<td>
<select name="age" >
<option value="none selected"> --- select --- </option>
<option value="junior">Junior</option>
<option value="adult">Adult</option>
<option value="corporate">Corporate</option>.
<option value="teacher">Teacher Training</option>
<option value="activity">Flamenco"</option>
</tr>
<tr>
<td align="right">School</td>
<td>
<div id ='schooldiv'>
<select name ="school">
<option value="none selected">Select Language First</option>
</div>
</tr>
<tr>
<td align="right">Level</td>
<td>
<div id="leveldiv">
<select name="level">
<option value="none selected">Select School First</option>
</div>
</tr>
<tr>
<td align="right">Duration</td>
<td>
<div id="durationdiv">
<select name="duration" >
<option value="none selected"> --- select --- </option>
</tr>
</div>

javascript

function getDuration(school)
{
{
xmlhttp=GetXmlHttpObject();
if (xmlhttp==null)
  {
  alert ("Browser does not support HTTP Request");
  return;
  }
var url="getduration.php";
url=url+"?school="+school;
url=url+"&sid="+Math.random();
xmlhttp.onreadystatechange=stateChanged;
xmlhttp.open("GET",url,true);
xmlhttp.send(null);
}

function stateChanged()
{
if (xmlhttp.readyState==4)
{
document.getElementById("durationdiv").innerHTML=xmlhttp.responseText;
}
}

function GetXmlHttpObject()
{
if (window.XMLHttpRequest)
  {
  // code for IE7+, Firefox, Chrome, Opera, Safari
  return new XMLHttpRequest();
  }
if (window.ActiveXObject)
  {
  // code for IE6, IE5
  return new ActiveXObject("Microsoft.XMLHTTP");
  }
return null;
}
}

function getLevel(school)
{
{
xmlhttp=GetXmlHttpObject();
if (xmlhttp==null)
  {
  alert ("Browser does not support HTTP Request");
  return;
  }
var url="findlevel.php";
url=url+"?school="+school;
url=url+"&sid="+Math.random();
xmlhttp.onreadystatechange=stateChanged;
xmlhttp.open("GET",url,true);
xmlhttp.send(null);
}

function stateChanged()
{
if (xmlhttp.readyState==4)
{
document.getElementById("leveldiv").innerHTML=xmlhttp.responseText;
}
}

function GetXmlHttpObject()
{
if (window.XMLHttpRequest)
  {
  // code for IE7+, Firefox, Chrome, Opera, Safari
  return new XMLHttpRequest();
  }
if (window.ActiveXObject)
  {
  // code for IE6, IE5
  return new ActiveXObject("Microsoft.XMLHTTP");
  }
return null;
}
}

function getSchool1(langid)
{
xmlhttp=GetXmlHttpObject();
if (xmlhttp==null)
  {
  alert ("Browser does not support HTTP Request");
  return;
  }
var url="findcity.php";
url=url+"?language="+langid;
url=url+"&sid="+Math.random();
xmlhttp.onreadystatechange=stateChanged;
xmlhttp.open("GET",url,true);
xmlhttp.send(null);
}

function stateChanged()
{
if (xmlhttp.readyState==4)
{
document.getElementById("schooldiv").innerHTML=xmlhttp.responseText;
}
}

function GetXmlHttpObject()
{
if (window.XMLHttpRequest)
  {
  // code for IE7+, Firefox, Chrome, Opera, Safari
  return new XMLHttpRequest();
  }
if (window.ActiveXObject)
  {
  // code for IE6, IE5
  return new ActiveXObject("Microsoft.XMLHTTP");
  }
return null;
}

findcity.php

<?php

$language = $_GET["language"];


mysql_connect("localhost", "root", "") or die(mysql_error());
  
  mysql_select_db("burkes1_jos") or die(mysql_error());


$query = mysql_query("SELECT s.school FROM ssa_schoolid AS s, ssa_lang AS l
WHERE l.langtype = '$language'
AND l.langid = s.langid
group by s.school")
or die (mysql_error()); 
?>
<select name="school" onChange="getLevel(this.value)";>
<option>Select School</option>
<? while($row = mysql_fetch_array($query)) { ?>
   <option value><?=$row['school']?></option>
<? } 
$school = $row['school'];?>
</select>

findlevel.php

<?php

$language = $_GET["language"];
$school = $_GET['school'];

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_lang as l, ssa_course as c
 where s.school = '$school'
 and s.schoolid = c.schoolid
 and c.schoolid = c.levelid
 group by le.leveltype")
or die (mysql_error()); 

?>

<select name ="level" onChange="getDuration(this.value)">
<option>Select Level</option>
<? while($row = mysql_fetch_array($query)) { ?>
   <option value><?=$row['leveltype']?></option>
<? } 
?>
</select>

Daved,

There are a few things to fix. The code below should get you started - see notes b below for what else to do:

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("schooldiv").innerHTML = xmlhttp.responseText;
			document.getElementById("schoolSelect").innerHTML = xmlhttp.responseText;
			document.getElementById("schoolSelect").disabled = 0;
		}
	};
	xmlhttp.open("GET",url,true);
	xmlhttp.send(null);
}
function getLevel(school){
	var xmlhttp = GetXmlHttpObject();
	if(!xmlhttp){ return; }
	var langid = document.getElementById("langSelect").value;
	var url = "findlevel.php" +
		"?language=" + langid +
		"&school=" + school +
		"&sid=" + Math.random();
	xmlhttp.onreadystatechange = function(){
		if (xmlhttp.readyState == 4){
//			document.getElementById("leveldiv").innerHTML = xmlhttp.responseText;
			document.getElementById("levelSelect").innerHTML = xmlhttp.responseText;
			document.getElementById("levelSelect").disabled = 0;
		}
	};
	xmlhttp.open("GET",url,true);
	xmlhttp.send(null);
}
function getDuration(level){
	var xmlhttp = GetXmlHttpObject();
	if(!xmlhttp){ return; }
	var langID = document.getElementById("langSelect").value;
	var schoolID = document.getElementById("schoolSelect").value;
	var url = "getduration.php" +
		"?language=" + langID +
		"&school=" + schoolID +
		"&level=" + level +
		"&sid=" + Math.random();
	xmlhttp.onreadystatechange = function(){
		if (xmlhttp.readyState == 4){
//			document.getElementById("durationdiv").innerHTML = xmlhttp.responseText;
			document.getElementById("durationSelect").innerHTML = xmlhttp.responseText;
			document.getElementById("durationSelect").disabled = 0;
		}
	};
	xmlhttp.open("GET",url,true);
	xmlhttp.send(null);
}
<form action="process.php" method="post">
<table>
<td align="right">Language of interest:</td>
<td>
<select id="langSelect" 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">Course Type</td>
<td>
<select name="age">
	<option value="none selected"> --- select --- </option>
	<option value="junior">Junior</option>
	<option value="adult">Adult</option>
	<option value="corporate">Corporate</option>
	<option value="teacher">Teacher Training</option>
	<option value="activity">Flamenco"</option>
</select>
</td>
</tr>
<tr>
<td align="right">School</td>
<td>
<select id="schoolSelect" name ="school" onChange="getLevel(this.value)" disabled>
	<option value="none selected">Select Language First</option>
</select>
</td>
</tr>
<tr>
<td align="right">Level</td>
<td>
<select id="levelSelect" name="level" onChange="getDuration(this.value)" disabled>
	<option value="none selected">Select School First</option>
</select>
</td>
</tr>
<tr>
<td align="right">Duration</td>
<td>
<select id="durationSelect" name="duration" disabled>
	<option value="none selected">Select Level First</option>
</select>
</td>
</tr>
</table>

NOTES

  1. Javascript tidied up (quite a bit)
  2. A more comprehensive version of GetXmlHttpObject is provded (and only one instance of it!)
  3. onChange handlers added to the "school" and "level" select menus (probably the main problem).
  4. request urls now built with language= and level= parameters where required.
  5. "shool", "level", "duration" menus now initially disabled and enabled when populated with options.
  6. Div wrappers around select menus now purged and select elements given their own ids (so they can be populated with options without destroying the <select> tags themselves).

Your PHP files, ("findcity.php", "findlevel.php", "getduration.php") must now return only options, without <select></select> containers.

Let us know how it goes.

Airshow

Hi

Thanks a million for the code and advice. It's certainly alot cleaner then mine!! The dropdown works fine when I specify a value in the query i.e 'madrid'. It doesn't work when I try to use a variable i.e $school.

The first dropdown works because findcity.php recognises $_GET. This is not the case for findlevel.php. I thought that using additional parameters language and level should have solved this.

The problem is still that the javascript isn't passing the variables to the URL or the PHP isn't able to receive/recognise them.

Its probably something really simple but I can't figure it out! Any more advice would be fantastic. Thanks again for your interest.

Daved,

Try inserting alert(url); immediately after url is composed in getLevel .

That will tell you whether or not the function is being called, and whether request is being composed properly.

If the request is bad, then it needs fixing in findLevel .

If the request is good, then you need to look at the code in findLevel .

Also: I've just spotted - you need to address the line <option value><?=$row['school']?></option> (probably in all three php files). No value is set.

Should be something like <option value=<?=$row['schoolVal']?>><?=$row['school']?></option> , (I'm guessing at 'schoolVal' - you need to replace with your actual database field name). You can test this with "view source" in the browser to see what was actually served.

Airshow

Thanks Airshow. Finally got it to work. It was the option value that was the main problem. Can't believe I didn't see that! Thanks for all your help, I wouldn't have stood a chance otherwise!

Sorry to revisit this one again. I'm having trouble getting the dropdown working in IE. I've tried switching the id to the <td> element and including the <select> element back the php file, but to no avail. (Only works for the first 2 dropdowns the id values are lost)

Does anybody know how to get this contraption working in IE another way?!?!?

I've heard the problem lies with inner.html and appendChild can be used to overcome this but I really have no idea how???

Any help greatly appreciated, I really need to get this sorted.

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

<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

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

<?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 :

document.getElementById("room").disabled = 0;

with

document.getElementById("room").setAttribute('disabled', 0);

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

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 <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.

<!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

Comments
Sovled it in one!

Works like a dream Airshow. Fair play. Once again you saved my ass!!!! Cheers!

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 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

Hello Daved83,
Hello Airshow,

lets me join this thread,
first of all i am a beginner need your advice in ajax, i have tried the code above and good, but i need your advice how to change the last result appear in text box not in select box. here is my code

<html>
<head>
<title>Roshan's Ajax dropdown code</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<?
#### Roshan's Ajax dropdown code with php
#### Copyright reserved to Roshan Bhattarai - nepaliboy007@yahoo.com
#### if you have any problem contact me at http://roshanbh.com.np
#### fell free to visit my blog http://php-ajax-guru.blogspot.com
?>
<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 = [
		[ 'country' , 'findcity.php' ],
		[ 'city'   , 'findvalue.php' ],
		[ 'value'   , '' ]
	];
	//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 method="post" action="" name="form1">
<table width="60%" border="0" cellspacing="0" cellpadding="0">
  <tr>
    <td width="150">Country</td>
    <td  width="150"><select name="country" id="country" onChange="getNextMenu(0)">
	<option value="">Select Country</option>
	<option value="1">USA</option>
	<option value="2">Canada</option>
        </select></td>
  </tr>
  <tr style="">
    <td>City</td>
    <td ><select name="city" id="city" onChange="getNextMenu(1)" disabled>
<option value="none selected"> Select country First</option> 
        </select></td>
  </tr>
  <tr style="">
    <td>Value</td>
    <td >
    <select name="value" id="value" disabled>
<option value="none selected"> Select city First </option> 
     </select>
   </td>
  </tr>
 
  <tr>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
  </tr>
  <tr>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
  </tr>
</table>
</form>
</body>
</html>

the last result code is :

<? $city=intval($_REQUEST['city']);
$link = mysql_connect('localhost', 'root', ''); //changet the configuration in required
if (!$link) {
    die('Could not connect: ' . mysql_error());
}
mysql_select_db('db_ajax');
$query="select val from city where id=$city";
$result=mysql_query($query);
$valrow=mysql_fetch_assoc($result);
?>
<input type="text" name="value" value="<?php echo $valrow['val']; ?>">

thank your help before

best regards

This article has been dead for over six months. Start a new discussion instead.