0

Hi all,

I posted up a thread a few weeks ago, regarding automatically updating a drop down list from a database using ajax.

Someone posted a reply suggesting i use the w3schools website for some help and i managed to put together something that worked for me.

However, i'm now coming across a problem where i need to use the ajax feature more than once on the same page.

I'll try post a link to give a sort of working example and i'll also try explain myself.

At the moment i have 4 select boxes:

Category
Sub Category

Manufacturer
Model

What happens, if i select a value from the Category list, the model list gets updated.

But what should happen is, Category updates sub category and then manufacturer updates model.

If i choose a value from manufacturer first, the model list updates correctly.

So as you can see it's kinda half working.

What i've been doing is calling two different .js files and using 2 different onChange events, hoping that it would update how i wanted it to.

<select name="cat_id" class="input" id="cat_id" onchange="subcatUpdate(this.value)">
<select name="man_id" class="input" id="man_id" onchange="modelUpdate(this.value)">

Below is a copy of my 2 .js files

var xmlhttp;

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

function stateChanged()
{
if (xmlhttp.readyState==4)
{
document.getElementById("subcat_id").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;
}
var xmlhttp;

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

function stateChanged()
{
if (xmlhttp.readyState==4)
{
document.getElementById("happy_id").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;
}

And finally my HTML/PHP Code

<table width="54%" cellpadding="5" cellspacing="5" class="table_style">
  <tr>
    <td width="21%"><label>Category:<br />
      <select name="cat_id" class="input" id="cat_id" onchange="subcatUpdate(this.value)">
          <option value="Please Select">Please Select</option>
      <?php
      		  // Open Connection to DB
			  require_once ('../include/config.inc_admin.php');
			  require_once (MYSQL);
			  
			  $q = "SELECT cat_id, cat_name FROM categories";
			  $r = mysqli_query ($dbc, $q) or trigger_error("Query: $q\n<br />MySQL Error: " . mysqli_error($dbc));
			  
			  while ($row = mysqli_fetch_array($r, MYSQLI_ASSOC)) {
			  	
				echo "<option value=" . $row['cat_id'] . ">" . $row['cat_name'] . "</option>"; 
			  }
      ?>
        </select></label></td>
    </tr>
  <tr>
    <td><label>Sub Category:<br />
    </label><div id="subcat_id"></div></td>
  </tr>
  <tr>
    <td><label>Manufacturer:<br />
        <select name="man_id" class="input" id="man_id" onchange="modelUpdate(this.value)">
          <option value="Please Select">Please Select</option>
          <?php
			  
			  $q = "SELECT man_id, manufacturer FROM manufacturers";
			  $r = mysqli_query ($dbc, $q) or trigger_error("Query: $q\n<br />MySQL Error: " . mysqli_error($dbc));
			  
			  while ($row = mysqli_fetch_array($r, MYSQLI_ASSOC)) {
			  	
			  	$man_id = $row['man_id'];
				echo "<option value=" . $row['man_id'] . ">" . $row['manufacturer'] . "</option>"; 
			  }
      ?>
        </select>
    </label></td>
  </tr>
  <tr>
    <td><label>Model:<br />
    </label><div id="happy_id"></div></td>
  </tr>

I've left out my php files for connecting to the database as i know these are functioning okay.

Is the method i'm usin the correct way to be going about it or am i missing something out which is causing me to have this problem?

Any help is greatly appreciated,

Regards,

Dan

4
Contributors
7
Replies
13
Views
7 Years
Discussion Span
Last Post by dan_ord
0

So, in short what are you trying to achieve, chaining 4 dropdowns [cat -> subcat -> manuf -> model] OR simply 2 X 2 chains [cat -> subcat AND manuf -> model]?

0

So, in short what are you trying to achieve, chaining 4 dropdowns [cat -> subcat -> manuf -> model] OR simply 2 X 2 chains [cat -> subcat AND manuf -> model]?

Hi,

Sorry if you did not understand me before, what i'm trying to do is the user will select a cat from the list and the subcat list will appear, populated with results from the DB, then they choose a manuf and then same happens again wit the models.

So in essence yes 2 x 2 chains

Any chance you could help with that?

Regards,

Dan.

Edited by dan_ord: n/a

0

OK first of all, this used to happen to me all the time before getting to grips with prototype.js (prototypejs.org). A workaround that I used to use was something like:

xmlhttp=GetXmlHttpObject(); for one function

xmlhttp2=GetXmlHttpObject2(); for another function

functions: GetXmlHttpObject() and another one called GetXmlHttpObject2()

This is obviously a wrong approach, but did the job (I think - it was a long time ago).

This is the reason I went with a js library as messing with the ajax object really annoyed me. Using prototype, conducting html updates is sooooo simple (as with other librearies, such as jQuery).

One solution:

Place the following code in a js file as reference it in the head area along with the prototype.js file.

function updateDD(dd){
  if(dd == 'man'){
      var param = "man=" + $F('man_id').value;    
      var tag_id = 'model_id';
  }else{
      var param = "cat="  + $F('cat_id').value;    
      var tag_id = 'subcat_id';
  }
  var url = "/includes/popDrops.php";
  var model = new Ajax.Updater(tag_id, url,{method: 'post',parameters: param});
}

Change your onchange attribute value in the man_id and cat_id select tag to:

onchange="updateDD('man');" and onchange="updateDD('cat');" respectively.


Your php include file (/includes/popDrops.php) will now receive a $_POST variable, which is either $_POST or $_POST.

You can then use:

//db connection info


if(isset($_POST['cat'])){
 $sql = mysql_query("...");
}elseif(isset($_POST['man'])){
 $sql = mysql_query("...");
}

while($data = mysql_fetch_array($sql)){
   echo "\n\t<option value=\"$r[0]\">{$r['name']}</option>";
}
//NOTE - only if 'name' is common field to both tables (model and subcat)

NOT TESTED - top of head thingy.

Edited by diafol: n/a

0

Hi,

thanks for the solution ardav! i'll give that a try today sometime and keep you posted on how it goes.

Much apprecaited!

Regards,

Dan

0

I'm with Ardav on using a framework for your JS / Ajax requests. It does pay to write out your scripts the long way in the beginning when you are learning just to get a feel for what the script is doing but you can literally turn this:

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

Into this:

function subcatUpdate(id, url)
{
     new Ajax.Updater(id,url,{asynchronous:true}); 
}

Big difference and a HUGE time saver.

The nice part is that if it is a "generic" request you can use function subcatUpdate(id, url) for as many Ajax requests as you want to by simply changing the id and url in your 'onclick'.

I swear by Prototype.js and it might be worth it for you to look into.

0

Hi everyone,

update on this post, sorry its been a while, been very busy!

Tried the code posted by ardav and tweaked it slighty to my needs and works spot on!

thanks very much, to all of you that contirbuted!

And i can deifinately see the advantages of using a framework such as prototype, as CFROG pointed out, the difference in the code size etc was clear to see!

Regards,

Dan

This question has already been answered. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.