Page 1 of 2 12 LastLast
Results 1 to 15 of 16
  1. #1
    Join Date
    Jan 2009
    Posts
    16

    Unanswered: Dynamic Drop Down Selection

    I think this is the right place to ask this question. I am looking to an human-error free search. Where there are several drop down boxes that are filtered based on the selection of a previous drop down. For example:

    You would have a Make Drop down menu. And depending on that selection only certain models would populate the next drop down. And so on if need be.

  2. #2
    Join Date
    Jan 2009
    Posts
    16
    I am sorry i forgot to mention this would be getting populated from a MySQL DB

  3. #3
    Join Date
    Feb 2009
    Location
    Iceland
    Posts
    14
    Hi.

    The *best* way to do that is to use AJAX.

    AJAX is used by client-side code, like JavaScript, to request data from the server, which the client-side code can then use to update the page without having to reload it.
    Which means that you can have your page load the contents of a second dropdown box as the user selects values from the first, without the user ever having to refresh the page.

    For example. If you have these two tables in your database:
    Code:
    Table: Category
    +------------+--------------+
    | CategoryID | CategoryName |
    +------------+--------------+
    | 1          | Cars         |
    | 2          | Bikes        |
    +------------+--------------+
    
    Table: Product
    +-----------+-------------+------------+
    | ProductID | ProductName | CategoryID |
    +-----------+-------------+------------+
    | 1         | Ferrari     | 1          |
    | 2         | BMW         | 1          |
    | 3         | Volvo       | 1          |
    | 4         | BMW         | 2          |
    | 5         | Some Bike   | 2          |
    +-----------+-------------+------------+
    And you want to display a dropdown for the categories, and populate a second dropdown with products based on the selection of the first dropdown.

    Like always, we build a index page. This would contain the basic HTML for the page, and include an external JavaScript file, where our client-side code will be stored.
    HTML Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    	<head>
    		<title>AJAX Dropdown Example</title>
    		<script type="text/javascript" src="Scripts.js"></script>
    	</head>
    	<body>
    		<h1>AJAX Dropdown Example</h1>
    		
    		<h5>Select please:</h5>
    		<form action="?" method="post" id="SelectForm">
    			<select name="CategoryID" id="CategorySelect" onchange="UpdateProducts(this.value);">
    				<!-- Will be added dynamically -->
    			</select>
    			<select name="ProductID" id="ProductSelect">
    				<!-- Will be added dynamically -->
    			</select>
    			
    			<br /><input type="submit" />
    		</form>
    	</body>
    </html>
    The first thing we need to do, is create our AJAX object.

    The AJAX object I am talking about is actually called XMLHttpRequest.
    The XMLHttpRequest object is meant to request updates from the server, and return that data back to the JavaScript code that called it.

    In it's simplest form, this function would create a XMLHttpRequest object, or bail out with an error if the browser doesn't support it.
    This code, like all the other JavaScript code, should be put in the "Scripts.js" file.
    Code:
    function CreateHttpRequest()
    {
    	if(window.XMLHttpRequest) { // Standard method
    		return new XMLHttpRequest();
    	}
    	else if(ActiveXObject) {  // IE craphola
    		return new ActiveXObject("Microsoft.XMLHTTP");
    	}
    	else {
    		throw new Error("This browser does not support AJAX.");
    	}
    }
    The AJAX part is only half the picture tho.
    For the AJAX code to fetch data from the server, the server must be able to provide it with the data.

    To do that, we create PHP scripts on the server that generate simple XML outputs, which the XMLHttpRequest object can read and pass on to the client-side code.

    The first PHP code we would need for this example is the one that provides the categories:
    PHP Code:
    <?php
    // Set the content type and print the XML header.
    // The periods are added to make sure they don't cause parse issues
    header("Content-Type: text/xml; charset=UTF-8");
    echo 
    '<''?xml version="1.0" encoding="UTF-8"?''>'"\n";

    // Open a MySQL connection
    $dbLink mysql_connect("localhost""user""passwd");
              
    mysql_select_db("test"$dbLink);
    if(!
    $dbLink) {
        die(
    "<error>"mysql_error() ."</error>");
    }

    // Get the category values
    $sql "SELECT `CategoryID`, `CategoryName` FROM `Category`";
    $result mysql_query($sql
        or die(
    "<error>"mysql_error() ."</error>");

    echo 
    '<root>';
    if(
    $result) {
        while(
    $row mysql_fetch_assoc($result)) {
            echo 
    "<option><id>{$row['CategoryID']}</id><name>{$row['CategoryName']}</name></option>";
        }
    }
    echo 
    '</root>';

    mysql_close($dbLink);
    JavaScript can not be used to create a XMLHttpRequest object, request the data from the PHP file, and update the page.

    We do that with this function:
    Code:
    function UpdateCategories()
    {
    	// Create the AJAX object
    	var xmlHttp = CreateHttpRequest();
    	
    	// Create the action that will be taken when the
    	// reponse has been received.
    	xmlHttp.onreadystatechange = function()
    	{
    		if(xmlHttp.readyState == 4 && xmlHttp.responseXML) {
    			// Load and clear the category element
    			var catElement = document.getElementById('CategorySelect');
    			while(catElement.options.length > 0) {
    				catElement.remove(0);
    			}
    			
    			// Add the new options to the category element
    			var optionElements = xmlHttp.responseXML.getElementsByTagName('option');
    			for(var i = 0; i < optionElements.length; i++) {
    				var id = optionElements[i].getElementsByTagName('id')[0].firstChild.nodeValue;
    				var name = optionElements[i].getElementsByTagName('name')[0].firstChild.nodeValue;
    				catElement.add(new Option(name, id), null);
    			}
    		}
    	}
    	
    	// Send the request
    	xmlHttp.open("GET", "GetCategories.php", true);
    	xmlHttp.send(null);
    }
    And now for the second dropdown.

    Again, we create a PHP script to fetch the data and return it in simple XML format. The only difference here is that this PHP code needs a category ID so it can select only products matching the category we selected.
    PHP Code:
    <?php
    // Set the content type and print the XML header.
    // The periods are added to make sure they don't cause parse issues
    header("Content-Type: text/xml; charset=UTF-8");
    echo 
    '<''?xml version="1.0" encoding="UTF-8"?''>'"\n";

    // Make sure a category ID was passed
    ($catID = @$_GET['CategoryID']) or $catID null;
    if(!
    is_numeric($catID) || $catID <= 0) {
        die(
    "<error>Invalid category ID</error>");
    }

    // Open a MySQL connection
    $dbLink mysql_connect("localhost""user""passwd");
              
    mysql_select_db("test"$dbLink);
    if(!
    $dbLink) {
        die(
    "<error>"mysql_error() ."</error>");
    }

    // Get the category values
    $sql "SELECT `ProductID`, `ProductName` 
            FROM `tProduct`
            WHERE `CategoryID` = 
    {$catID}";
    $result mysql_query($sql
        or die(
    "<error>"mysql_error() ."</error>");


    if(
    $result && mysql_num_rows($result) > 0) {
        echo 
    '<root>';
        while(
    $row mysql_fetch_assoc($result)) {
            echo 
    "<option><id>{$row['ProductID']}</id><name>{$row['ProductName']}</name></option>";
        }
        echo 
    '</root>';
    }
    else {
        echo 
    "<error>No options found</error>";
    }

    mysql_close($dbLink);
    ?>
    And to call this PHP code and update the second drop-down, we need a new function in our JavaScript file. This function should be called in the Category <select> onchange event:
    Code:
    function UpdateProducts(pCatID)
    {
    	// Create the AJAX object
    	var xmlHttp = CreateHttpRequest();
    	
    	// Create the action that will be taken when the
    	// reponse has been received.
    	xmlHttp.onreadystatechange = function()
    	{
    		if(xmlHttp.readyState == 4 && xmlHttp.responseXML) {
    			// Load and clear the category element
    			var prodElement = document.getElementById('ProductSelect');
    			while(prodElement.options.length > 0) {
    				prodElement.remove(0);
    			}
    			
    			// Add the new options to the category element
    			var optionElements = xmlHttp.responseXML.getElementsByTagName('option');
    			if (optionElements.length == 0) {
    				out.innerHTML += xmlHttp.responseText + "<br />";
    			}
    			for(var i = 0; i < optionElements.length; i++) {
    				var id = optionElements[i].getElementsByTagName('id')[0].firstChild.nodeValue;
    				var name = optionElements[i].getElementsByTagName('name')[0].firstChild.nodeValue;
    				prodElement.add(new Option(name, id), null);
    			}
    		}
    	}
    	
    	// Send the request
    	xmlHttp.open("GET", "GetProducts.php?CategoryID=" + pCatID, true);
    	xmlHttp.send(null);
    }
    And finally, to populate both boxes when the page is loaded, we add the two Update functions to the onload event.
    This should be at the top of the "Scripts.js" file
    Code:
    window.onload = function()
    {
    	UpdateCategories();
    	UpdateProducts(1);
    }
    And that's it.
    Put all that together and you should have a small working example of this.

  4. #4
    Join Date
    Jan 2009
    Posts
    16
    Thank you very much. Got around to doing this part of the website finally. However whenever i run this i get an invalid category id error. Ugh always something.

  5. #5
    Join Date
    Feb 2009
    Location
    Iceland
    Posts
    14
    Hey.

    The "Invalid category ID" error would only be shown if the CategoryID being passed to the second PHP script is invalid.
    That script needs to be always called with the added "?CategoryID=x" string to the URL, where "x" needs to be a number higher than 0.

    If you can't locate the problem, post your code here, both the PHP and the Javascript function, and I'll see if I can help find it.

    Also note, if you are using my exact code, that the SQL query later in that page has an extra "t" in the table name. Just in case you run into that problem later

  6. #6
    Join Date
    Jan 2009
    Posts
    16
    Yes i noticed that the category id has to be greater then 0 at first i thought that was the issue. But i fixed my id's so that it is no longer an issue. But it would appear that i am not getting a proper output from the updateproducts function. I am curious is there anything i have to install on my server for it to understand ajax? or is this all being done by the browser?

    Here is my pages code I took out my password and such, sorry:

    Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    	<head>
    		<title>AJAX Dropdown Example</title>
    		
    <script type="text/javascript" src="Scripts.js"></script>
    	</head>
    	<body>
    		<h1>AJAX Dropdown Example</h1>
    		
    		<h5>Select please:</h5>
    		<form action="" method="post" id="SelectForm">
    			<select name="CategoryID" id="CategorySelect" onchange="UpdateProducts(1);">
    				<?php 
    // Set the content type and print the XML header. 
    // The periods are added to make sure they don't cause parse issues 
    header("Content-Type: text/xml; charset=UTF-8"); 
    echo '<'. '?xml version="1.0" encoding="UTF-8"?'. '>'. "\n"; 
    
    // Open a MySQL connection 
    $dbLink = mysql_connect("####", "####", "####"); 
              mysql_select_db("####", $dbLink); 
    if(!$dbLink) { 
        die("<error>". mysql_error() ."</error>"); 
    } 
    
    // Get the category values 
    $sql = "SELECT `id`, `desc` FROM `categories`"; 
    $result = mysql_query($sql)  
        or die("<error>". mysql_error() ."</error>"); 
    
    echo '<root>'; 
    if($result) { 
        while($row = mysql_fetch_assoc($result)) { 
            echo "<option><id>{$row['id']}</id><name>{$row['desc']}</name></option>"; 
        } 
    } 
    echo '</root>'; 
    
    ?>
    			</select>
    			<select name="ProductID" id="ProductSelect">
    <?php 
    // Set the content type and print the XML header. 
    // The periods are added to make sure they don't cause parse issues 
    header("Content-Type: text/xml; charset=UTF-8"); 
    echo '<'. '?xml version="1.0" encoding="UTF-8"?'. '>'. "\n"; 
    //$catID = 0;
    // Make sure a category ID was passed 
    ($catID = $_GET['CategoryID']) or $catID = null; 
    if(!is_numeric($catID) || $catID < 0) { 
        die("<error>Invalid category ID</error>"); 
    } 
    
    // Open a MySQL connection 
    $dbLink = mysql_connect("####", "####", "####"); 
              mysql_select_db("####", $dbLink); 
    if(!$dbLink) { 
        die("<error>". mysql_error() ."</error>"); 
    } 
    
    // Get the category values 
    $sql = "SELECT `id`, `desc` FROM `trades_list` WHERE `sub_id` = {$catID}"; 
    $result = mysql_query($sql)  
        or die("<error>". mysql_error() ."</error>"); 
    
    
    if($result && mysql_num_rows($result) > 0) { 
        echo '<root>'; 
        while($row = mysql_fetch_assoc($result)) { 
            echo "<option><id>{$row['id']}</id><name>{$row['desc']}</name></option>"; 
        } 
        echo '</root>'; 
    } 
    else { 
        echo "<error>No options found</error>"; 
    } 
    
    ?>
    			</select>
    			
    			<br /><input type="submit" />
    		</form>
    	</body>
    </html>
    And here is my scripts.js:

    Code:
    window.onload = function()
    {
    	UpdateCategories();
    	UpdateProducts(1);
    }
    
    
    function CreateHttpRequest()
    {
    	if(window.XMLHttpRequest) { // Standard method
    		return new XMLHttpRequest();
    	}
    	else if(ActiveXObject) {  // IE craphola
    		return new ActiveXObject("Microsoft.XMLHTTP");
    	}
    	else {
    		throw new Error("This browser does not support AJAX.");
    	}
    }
    
    function UpdateCategories()
    {
    	// Create the AJAX object
    	var xmlHttp = CreateHttpRequest();
    	
    	// Create the action that will be taken when the
    	// reponse has been received.
    	xmlHttp.onreadystatechange = function()
    	{
    		if(xmlHttp.readyState == 4 && xmlHttp.responseXML) {
    			// Load and clear the category element
    			var catElement = document.getElementById('CategorySelect');
    			while(catElement.options.length > 0) {
    				catElement.remove(0);
    			}
    			
    			// Add the new options to the category element
    			var optionElements = xmlHttp.responseXML.getElementsByTagName('option');
    			for(var i = 0; i < optionElements.length; i++) {
    				var id = optionElements[i].getElementsByTagName('id')[0].firstChild.nodeValue;
    				var name = optionElements[i].getElementsByTagName('name')[0].firstChild.nodeValue;
    				catElement.add(new Option(name, id), null);
    			}
    		}
    	}
    	
    	// Send the request
    	xmlHttp.open("GET", "GetCategories.php", true);
    	xmlHttp.send(null);
    }
    
    function UpdateProducts(pCatID)
    {
    	// Create the AJAX object
    	var xmlHttp = CreateHttpRequest();
    	
    	// Create the action that will be taken when the
    	// reponse has been received.
    	xmlHttp.onreadystatechange = function()
    	{
    		if(xmlHttp.readyState == 4 && xmlHttp.responseXML) {
    			// Load and clear the category element
    			var prodElement = document.getElementById('ProductSelect');
    			while(prodElement.options.length > 0) {
    				prodElement.remove(0);
    			}
    			
    			// Add the new options to the category element
    			var optionElements = xmlHttp.responseXML.getElementsByTagName('option');
    			if (optionElements.length == 0) {
    				out.innerHTML += xmlHttp.responseText + "<br />";
    			}
    			for(var i = 0; i < optionElements.length; i++) {
    				var id = optionElements[i].getElementsByTagName('id')[0].firstChild.nodeValue;
    				var name = optionElements[i].getElementsByTagName('name')[0].firstChild.nodeValue;
    				prodElement.add(new Option(name, id), null);
    			}
    		}
    	}
    	
    	// Send the request
    	xmlHttp.open("GET", "GetProducts.php?CategoryID=" + pCatID, true);
    	xmlHttp.send(null);
    }

  7. #7
    Join Date
    Feb 2009
    Location
    Iceland
    Posts
    14
    Ahh ok. I see the confusion.

    The two PHP code snippets need to be in two separate PHP files, "GetCategories.php" and "GetProducts.php", respectively.
    (I should have been more clear on that in my post.)

    AJAX (XMLHttpRequest) is a method used by the browsers to do a totally independent HTTP request, completely separate from the main HTTP request that got you the page the Javascript is being executed on.
    The two PHP scripts are mean to create XML output in response to those independent requests, and are not meant to be a part of the main code.

  8. #8
    Join Date
    Jan 2009
    Posts
    16
    Ahhh it is so much clearer now. I was confused by the xmlhttp open request for the getcategories.php i was like where does that come into play. But now this is much better. This works perfectly thank you so much.

  9. #9
    Join Date
    Jan 2009
    Posts
    16
    Another question for you. I am now trying to add on to this page. I want to have another couple of drop downs that do the same thing. So i have duplicated the number of .php files. and also the script code. I then changed the variables that i could see. but when i load it up, the second set of drop downs are completely empty. Any ideas on what i might be missing?

  10. #10
    Join Date
    Jan 2009
    Posts
    16
    Yeah i figured it out. I misspelled my function call at the beginning of my scripts file.

  11. #11
    Join Date
    Jan 2009
    Posts
    16
    Atli,

    I am sorry but i dont know javascript that well and now the javascript is causing errors in IE, chrome works fine and so does mozilla.

    Code:
    var catElement = document.getElementById('CategorySelect');
    			while(catElement.options.length > 0) {
    				catElement.remove(0);
    			}
    Error: "Object required" - catElement.remove(0);

    Code:
    var optionElements = xmlHttp.responseXML.getElementsByTagName('option');
    			for(var i = 0; i < optionElements.length; i++) {
    				var id = optionElements[i].getElementsByTagName('id')[0].firstChild.nodeValue;
    				var name = optionElements[i].getElementsByTagName('name')[0].firstChild.nodeValue;
    				[red]catElement.add(new Option(name, id), null);
    			}[/red]
    Error: "Type Mismatch" - on red text

    I am sorry to keep bugging you about this. Thank you for all of the help you have provided thus far.

  12. #12
    Join Date
    Feb 2009
    Location
    Iceland
    Posts
    14
    Hey socca.

    I can't see a reason for your first error. There is nothing in the code snipped you posted that would explain it. Perhaps there is something in the surrounding code that would?

    For your second error, it seems that IE deviates from the standard in how it adds options to a select element.
    To fix it, you can add a try...catch block to catch the IE error and use the alternative, non-standard method.
    PHP Code:
    try {
        
    // Standard method
        
    catElement.add(new Option(nameid), null);
    } catch (
    e) {
        
    // To fix the IE bug
        
    catElement.add(new Option(nameid));


  13. #13
    Join Date
    Feb 2009
    Location
    Iceland
    Posts
    14
    Quote Originally Posted by Atli View Post
    For your second error, it seems that IE deviates from the standard in how it adds options to a select element.
    It appears, though, that Firefox is the only one of the major browsers that enforces the standard strictly enough that this matters. All the other major browsers seem happy leaving the second parameter out, as IE does. (Although they all allow it as well.)

    And it seems that the second parameter will become optional in HTML5. (Not that that will fix this in IE. Not until like 20 years from now when IE adds support for it, anyways )

    In any case, to save a couple of CPU cycles, you could rewrite it as thus:
    PHP Code:
    try {
        
    // Non-standard HTML4 / HTML5
        
    catElement.add(new Option(nameid));
    } catch (
    e) {
        
    // Standard HTML4
        
    catElement.add(new Option(nameid), null);


  14. #14
    Join Date
    Jan 2009
    Posts
    16
    Ok interesting facts. I will def need to keep reading to keep on learning. To help out here is my scripts.js file:
    Code:
    window.onload = function()
    {
    	UpdateCategories();
    	UpdateProducts(1);
    	UpdateProjCategories();
    	UpdateProjProducts(1);
    	UpdateStates();
    	UpdateCounties(1);
    }
    
    
    function CreateHttpRequest()
    {
    	if(window.XMLHttpRequest) { // Standard method
    		return new XMLHttpRequest();
    	}
    	else if(ActiveXObject) {  // IE craphola
    		return new ActiveXObject("Microsoft.XMLHTTP");
    	}
    	else {
    		throw new Error("This browser does not support AJAX.");
    	}
    }
    
    function UpdateCategories()
    {
    	// Create the AJAX object
    	var xmlHttp = CreateHttpRequest();
    	
    	// Create the action that will be taken when the
    	// reponse has been received.
    	xmlHttp.onreadystatechange = function()
    	{
    		if(xmlHttp.readyState == 4 && xmlHttp.responseXML) {
    			// Load and clear the category element
    			var catElement = document.getElementById('CategorySelect');
    			while(catElement.options.length > 0) {
    				catElement.remove(0);
    			}
    			
    			// Add the new options to the category element
    			var optionElements = xmlHttp.responseXML.getElementsByTagName('option');
    			for(var i = 0; i < optionElements.length; i++) {
    				var id = optionElements[i].getElementsByTagName('id')[0].firstChild.nodeValue;
    				var name = optionElements[i].getElementsByTagName('name')[0].firstChild.nodeValue;
    				catElement.add(new Option(name, id), null);			    
    			}
    		}
    	}
    	
    	// Send the request
    	xmlHttp.open("GET", "GetCategories.php", true);
    	xmlHttp.send(null);
    }
    
    function UpdateProducts(pCatID)
    {
    	// Create the AJAX object
    	var xmlHttp = CreateHttpRequest();
    	
    	// Create the action that will be taken when the
    	// reponse has been received.
    	xmlHttp.onreadystatechange = function()
    	{
    		if(xmlHttp.readyState == 4 && xmlHttp.responseXML) {
    			// Load and clear the category element
    			var prodElement = document.getElementById('ProductSelect');
    			while(prodElement.options.length > 0) {
    				prodElement.remove(0);
    			}
    			
    			// Add the new options to the category element
    			var optionElements = xmlHttp.responseXML.getElementsByTagName('option');
    			if (optionElements.length == 0) {
    				out.innerHTML += xmlHttp.responseText + "<br />";
    			}
    			for(var i = 0; i < optionElements.length; i++) {
    				var id = optionElements[i].getElementsByTagName('id')[0].firstChild.nodeValue;
    				var name = optionElements[i].getElementsByTagName('name')[0].firstChild.nodeValue;
    				prodElement.add(new Option(name, id), null);
    			}
    		}
    	}
    	
    	// Send the request
    	xmlHttp.open("GET", "GetProducts.php?CategoryID=" + pCatID, true);
    	xmlHttp.send(null);
    }
    
    function UpdateProjCategories()
    {
    	// Create the AJAX object
    	var xmlHttp = CreateHttpRequest();
    	
    	// Create the action that will be taken when the
    	// reponse has been received.
    	xmlHttp.onreadystatechange = function()
    	{
    		if(xmlHttp.readyState == 4 && xmlHttp.responseXML) {
    			// Load and clear the category element
    			var catElement = document.getElementById('ProjCategorySelect');
    			while(catElement.options.length > 0) {
    				catElement.remove(0);
    			}
    			
    			// Add the new options to the category element
    			var optionElements = xmlHttp.responseXML.getElementsByTagName('option');
    			for(var i = 0; i < optionElements.length; i++) {
    				var id = optionElements[i].getElementsByTagName('id')[0].firstChild.nodeValue;
    				var name = optionElements[i].getElementsByTagName('name')[0].firstChild.nodeValue;
    				catElement.add(new Option(name, id), null);
    			}
    		}
    	}
    	
    	// Send the request
    	xmlHttp.open("GET", "GetProjCategories.php", true);
    	xmlHttp.send(null);
    }
    
    function UpdateProjProducts(pCatID)
    {
    	// Create the AJAX object
    	var xmlHttp = CreateHttpRequest();
    	
    	// Create the action that will be taken when the
    	// reponse has been received.
    	xmlHttp.onreadystatechange = function()
    	{
    		if(xmlHttp.readyState == 4 && xmlHttp.responseXML) {
    			// Load and clear the category element
    			var prodElement = document.getElementById('ProjProductSelect');
    			while(prodElement.options.length > 0) {
    				prodElement.remove(0);
    			}
    			
    			// Add the new options to the category element
    			var optionElements = xmlHttp.responseXML.getElementsByTagName('option');
    			if (optionElements.length == 0) {
    				out.innerHTML += xmlHttp.responseText + "<br />";
    			}
    			for(var i = 0; i < optionElements.length; i++) {
    				var id = optionElements[i].getElementsByTagName('id')[0].firstChild.nodeValue;
    				var name = optionElements[i].getElementsByTagName('name')[0].firstChild.nodeValue;
    				prodElement.add(new Option(name, id), null);
    			}
    		}
    	}
    	
    	// Send the request
    	xmlHttp.open("GET", "GetProjProducts.php?ProjCategoryID=" + pCatID, true);
    	xmlHttp.send(null);
    }
    
    function UpdateStates()
    {
    	// Create the AJAX object
    	var xmlHttp = CreateHttpRequest();
    	
    	// Create the action that will be taken when the
    	// reponse has been received.
    	xmlHttp.onreadystatechange = function()
    	{
    		if(xmlHttp.readyState == 4 && xmlHttp.responseXML) {
    			// Load and clear the category element
    			var catElement = document.getElementById('StateSelect');
    			while(catElement.options.length > 0) {
    				catElement.remove(0);
    			}
    			
    			// Add the new options to the category element
    			var optionElements = xmlHttp.responseXML.getElementsByTagName('option');
    			for(var i = 0; i < optionElements.length; i++) {
    				var id = optionElements[i].getElementsByTagName('id')[0].firstChild.nodeValue;
    				var name = optionElements[i].getElementsByTagName('name')[0].firstChild.nodeValue;
    				catElement.add(new Option(name, id), null);
    			}
    		}
    	}
    	
    	// Send the request
    	xmlHttp.open("GET", "GetState.php", true);
    	xmlHttp.send(null);
    }
    
    function UpdateCounties(pCatID)
    {
    	// Create the AJAX object
    	var xmlHttp = CreateHttpRequest();
    	
    	// Create the action that will be taken when the
    	// reponse has been received.
    	xmlHttp.onreadystatechange = function()
    	{
    		if(xmlHttp.readyState == 4 && xmlHttp.responseXML) {
    			// Load and clear the category element
    			var countElement = document.getElementById('CountySelect');
    			while(countElement.options.length > 0) {
    				countElement.remove(0);
    			}
    			
    			// Add the new options to the category element
    			var optionElements = xmlHttp.responseXML.getElementsByTagName('option');
    			if (optionElements.length == 0) {
    				out.innerHTML += xmlHttp.responseText + "<br />";
    			}
    			for(var i = 0; i < optionElements.length; i++) {
    				var id = optionElements[i].getElementsByTagName('id')[0].firstChild.nodeValue;
    				var name = optionElements[i].getElementsByTagName('name')[0].firstChild.nodeValue;
    				countElement.add(new Option(name, id), null);
    			}
    		}
    	}
    	
    	// Send the request
    	xmlHttp.open("GET", "GetCounty.php?StateID=" + pCatID, true);
    	xmlHttp.send(null);
    }
    and if you want to see what this does in real life the page is myneighborhoodcontractor.com/projectser.html

    It is so frustrating that each browser differs so much.

  15. #15
    Join Date
    Feb 2009
    Location
    Iceland
    Posts
    14
    On that URL you posted you appear to have the "IDs of the <select> elements as "ProjCategorySelect" and "ProjProductSelect" in your HTML, but your JavaScript tries to fetch them as "CategorySelect" and "ProjectSelect".
    This would be the reason for your first error. You need to rename them either in the HTML or in the JavaScript so they match.

    And the other error can be fixed by what I suggested in the last post.

    It is so frustrating that each browser differs so much.
    Agreed. Browser incompatibilities are a major pain. Worst part about web development; having to tear your beautiful code apart to make it work in IE

    But if you just stick to the standards your code will usually only need to be "fixed" (or rather "broken") to work in IE. All the other major browsers stick closely enough to the standards, that they are usually compatible with each other.

    A lot of people make the mistake of writing for IE first, because it has the largest market-share, but that will usually just make it harder to get the code compatible with all the other major browsers. - It's easier to modify standard code to work in a broken browser (IE), than to write broken code and try to get that to work properly in all the browsers. (Each browser tends to handle broken code in it's own unique way - there is no standard to rely on for how to render broken code )

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •