Use of a select box produced by AJAX

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • mikek12004
    New Member
    • Sep 2008
    • 200

    Use of a select box produced by AJAX

    I have a search form with the first two fields being country and city. When the user selects a country I want the city select box to display only the cities of that country (I have already implement what cities belong to each country in a mysql database). I didn't wish to reload the entire page so I wish ajax. I placed the entire city select box in a div and when the user select a country I used ajax to initiate a PHP script replacing the current select box (which showed all the cities) with another (same I kept same name- hence same id, I tend to put the value of the name property also to the id) all goes well and the new select box is shown both in IE and firefox, but when I press the submit button in firefox it does not take into account the choice I have put in the generated city select box! In IE works just fine any ideas?
  • acoder
    Recognized Expert MVP
    • Nov 2006
    • 16032

    #2
    Post your code so we can see where the problem might be.

    Comment

    • FLEB
      New Member
      • Aug 2008
      • 30

      #3
      You could try clearing out and replacing only the <option> elements and not the entire <select>. I can't say as I know what the actual problem might be, given the description, but that's something to try.

      Comment

      • iam_clint
        Recognized Expert Top Contributor
        • Jul 2006
        • 1207

        #4
        I would use DOM to remove all the children on the select box and use new option to add all the new options back.. This should keep you much more cross browser friendly
        Example Provided
        [CODE=javascript]
        function respawnOptions( ) {
        var selbox=document .getElementById ("selbox");
        removeChildren( selbox);
        /*Ajax stuff here.. have php respond with a delimited value of some sort example |*/
        var spVal=ajaxRespo nse.split("|");
        for (var i=0; i<spVal.length ; i++)
        {
        /*#### Example of new Option("Display Text", "Value") ###*/
        selbox.options[selbox.options. length] = new Option(spVal[i], spVal[i]);
        }
        }


        function removeChildren( obj)
        {
        while (obj.hasChildNo des())
        {
        obj.removeChild (obj.firstChild );
        }
        }
        [/CODE]

        Comment

        • rnd me
          Recognized Expert Contributor
          • Jun 2007
          • 427

          #5
          remember that by killing the orig select, you also kill any events associated with it. if you re-use the name and id, you might be confusing bound events, since they don't disappear when the html is replaced.


          ps: a simpler, highly compatible way to clear the select is:
          selbox.options. length = 0;

          Comment

          • freddieMaize
            New Member
            • Aug 2008
            • 85

            #6
            Hey Mikek,

            i'm not getting you fully. But here is the code that i used for the same case. I mean, country and city case.

            Code:
             xmlHttp.onreadystatechange=function()
                    {
                    if(xmlHttp.readyState==4){
                    status_name = xmlHttp.responseText;
                    if ((status_name=="") || (status_name==null))
                    {
                    removeOptionLast2();
                    }
                    else
                    {
                    removeOptionLast2();
                    var col_array1=status_name.split("/");
                    // alert(col_array[0]);
                    var part_num1=0;
                    while (part_num1 < col_array1.length)
                    {
                    var a=document.createElement('option');
                    a.text=col_array1[part_num1];
                    a.value=col_array1[part_num1];
                    var b=document.getElementById("modify_city_name");
                    try
                    {
                    b.add(a,null); // standards compliant
                    }
                    catch(ex)
                    {
                    b.add(a); // IE only
                    }                        
                    part_num1+=1;
                    }        
                    }       
                    }
                    }
                    function removeOptionLast2(){
                    var i;
                    var remove_status_name = document.getElementById('modify_city_name');
                    for(i=remove_status_name.length; i>=0; i--){
                    remove_status_name.remove(i);
                    }
                    }
            Hope this helps. Post back if any queries

            Regards,
            fREDDIE

            Comment

            • acoder
              Recognized Expert MVP
              • Nov 2006
              • 16032

              #7
              Originally posted by rnd me
              ps: a simpler, highly compatible way to clear the select is:
              selbox.options. length = 0;
              Yes, definitely agree on this one. Nice and simple.

              Comment

              • acoder
                Recognized Expert MVP
                • Nov 2006
                • 16032

                #8
                Originally posted by freddieMaize
                i'm not getting you fully. But here is the code that i used for the same case. I mean, country and city case.
                Freddie, you should indent your code properly so that it's much easier to follow for yourself and others. For example, from lines 30-33, you have closing brackets on each line. How do you easily match them up? OK, this is a small example, but what if you have hundreds of lines of code?

                Comment

                • freddieMaize
                  New Member
                  • Aug 2008
                  • 85

                  #9
                  Originally posted by acoder
                  Freddie, you should indent your code properly so that it's much easier to follow for yourself and others. For example, from lines 30-33, you have closing brackets on each line. How do you easily match them up? OK, this is a small example, but what if you have hundreds of lines of code?
                  Okay... won't repeat them...

                  Code:
                  xmlHttp.onreadystatechange=function()
                              {
                                  if(xmlHttp.readyState==4){
                                      status_name = xmlHttp.responseText;
                                      if ((status_name=="") || (status_name==null))
                                          {
                                              removeOptionLast2();
                                          }
                                          else
                                              {
                                                  removeOptionLast2();
                                                  var col_array1=status_name.split("/");
                                                  // alert(col_array[0]);
                                                  var part_num1=0;
                                                  while (part_num1 < col_array1.length)
                                                      {
                                                          var a=document.createElement('option');
                                                          a.text=col_array1[part_num1];
                                                          a.value=col_array1[part_num1];
                                                          var b=document.getElementById("modify_city_name");
                                                          try
                                                          {
                                                              b.add(a,null); // standards compliant
                                                          }
                                                          catch(ex)
                                                          {
                                                              b.add(a); // IE only
                                                          }                        
                                                          part_num1+=1;
                                                      }        
                                                  }       
                                              }
                                          }
                                          function removeOptionLast2(){
                                              var i;
                                              var remove_status_name = document.getElementById('modify_city_name');
                                              for(i=remove_status_name.length; i>=0; i--){
                                                  remove_status_name.remove(i);
                                              }
                                          }
                  fREDDIE

                  Comment

                  • acoder
                    Recognized Expert MVP
                    • Nov 2006
                    • 16032

                    #10
                    Well, that is better though the indenting has gone a bit awry in the last part of the code.

                    PS. we'll leave it there, otherwise this thread would be truly hijacked.

                    Comment

                    • freddieMaize
                      New Member
                      • Aug 2008
                      • 85

                      #11
                      Originally posted by acoder
                      Well, that is better though the indenting has gone a bit awry in the last part of the code.

                      PS. we'll leave it there, otherwise this thread would be truly hijacked.
                      acoder,
                      Initially I tired with indention but it looked (now you know how it looks like) crooked. So I aligned them to left (which in not understandable) . Gosh!

                      Like you said, we ll leave it here. I just want to know if that code would help Mike. Because, end of the day thats what would count:)

                      fREDDIE

                      Comment

                      • mikek12004
                        New Member
                        • Sep 2008
                        • 200

                        #12
                        Thanks for your many replies, actually I'm quite new to web programming so I have a lot of thinks I cannot do.
                        The page with the form is in the file search_modela.p hp since it is quite big I believe the only important part is the lines
                        Code:
                        <script src="selectcity.js"></script>
                        and
                        Code:
                        <td width="157"><select name="country" class="style1" onchange="showcity(this.value)">
                                                      <option value="A" selected="selected">Any</option>
                        <?php				   		   $q1="SELECT DISTINCT country FROM models WHERE country!='' ORDER BY country asc";
                        							   $r1=mysql_query($q1);
                        								while($lines1=mysql_fetch_array($r1))
                        								{
                        ?>
                                                      		<option  value="<?php echo $lines1[0]; ?>" ><?php echo $lines1[0]; ?></option>
                        <?php					
                        								}
                        ?>
                                                    	</select>                            </td>
                                                </tr>
                                                 <tr height="30">
                                                    <td>Πόλη:</td>
                                                    <td>
                                                    <select name="city" class="style1" id="city">
                                                      <option value="A" selected="selected">Any</option>
                        <?php				   			$query="SELECT DISTINCT city FROM models WHERE city!='' ORDER BY city asc";
                        								$result=mysql_query($query) or die("Failed :" . mysql_error());
                        								while($lines=mysql_fetch_array($result))
                        								{
                        ?>
                                                      		<option value="<?php echo $lines[0]; ?>" ><?php echo $lines[0]; ?></option>
                        <?php					
                        								}
                        ?>
                                                    	</select>                           
                                                        </td>
                        (actually in dreamweaver I have it aligned using tab but when I copied them here they showed like this plus I can't seem to use tab to correctly align them)

                        this file includes the select city.js which is
                        Code:
                        var xmlHttp 
                        
                        function showcity(str)
                        { 
                        	xmlHttp=GetXmlHttpObject()
                        	if (xmlHttp==null)
                        	{
                        		 alert ("Browser does not support HTTP Request")
                        		 return
                            }
                        	
                        	var url="getcity.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 || xmlHttp.readyState=="complete")
                        	{ 
                         		document.getElementById("city").innerHTML=xmlHttp.responseText 
                         	} 
                        }
                        
                        function GetXmlHttpObject()
                        {
                        	var xmlHttp=null;
                        	try
                         	{
                         // Firefox, Opera 8.0+, Safari
                         		xmlHttp=new XMLHttpRequest();
                         	}
                        	catch (e)
                         	{
                         //Internet Explorer
                         		try
                          		{
                          			xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
                          		}
                         		
                        		catch (e)
                          		{
                          			xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
                          		}
                         	}
                        
                        	return xmlHttp;
                        }
                        I have found this file ready on http://www.w3schools.c om/ajax/ajax_database.a sp which is basically an example I based on, this js calls the getcity.php which is
                        Code:
                        <?php
                        include("./config.php");
                        $q=$_GET["q"];
                        echo  "<option value='A' selected='selected'>Any</option>";
                        $sql="SELECT DISTINCT city FROM models WHERE city!='' and country= '".$q."' ORDER BY city asc";
                        if ($q=="A")
                        $sql="SELECT DISTINCT city FROM models WHERE city!='' ORDER BY city asc";
                        $result = mysql_query($sql);
                        while($lines=mysql_fetch_array($result))
                        {
                        
                           echo "<option value='".iconv("iso-8859-7","utf-8","$lines[0]")."'>".iconv("iso-8859-7","utf-8","$lines[0]")."</option>";
                        			
                        }
                        
                        ?>
                        I removed the div tag around the select box named city and tried to replace only the options tags within the select (as shown in getcity.php) now it works fine on firefox but doesn't work on IE! So basically I have two solutions each playing only to one browser (it's somewhat frustrating!) Any idea for a unified solution?
                        Plus any tutorials on the web or books you could recommend me
                        PS The instructions said wrapping code around CODE tag so what's the use of the PHP and HTML tags which can be inserted from the forum toolbar?
                        Thanks again for your trouble

                        Comment

                        • acoder
                          Recognized Expert MVP
                          • Nov 2006
                          • 16032

                          #13
                          Instead of returning options and setting the innerHTML of the select, return a string delimited by a special character, e.g. see the post by iam_clint above. Then you can split on that character and then populate the select using JavaScript. Other alternatives are to use XML or JSON.
                          Originally posted by mikek12004
                          Plus any tutorials on the web or books you could recommend me
                          See the Offsite Links sticky thread.
                          Originally posted by mikek12004
                          PS The instructions said wrapping code around CODE tag so what's the use of the PHP and HTML tags which can be inserted from the forum toolbar?
                          The PHP and HTML tags are for PHP and HTML code respectively. In the past, the code was color-coded based on language, but that has temporarily been removed and hopefully added back in the near future.

                          Comment

                          • iam_clint
                            Recognized Expert Top Contributor
                            • Jul 2006
                            • 1207

                            #14
                            If you want to have your server reply with xml.. example
                            Code:
                            <xml>
                              <item>blah</item>
                              <size>2</size>
                            </xml>
                            You can use javascript like this to parse it.
                            Code:
                            /*########### XML Parser ############*/
                            if (window.ActiveXObject) { //ie
                              var xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
                              xmlDoc.loadXML(str);
                            } else { //firefox
                              var parser=new DOMParser();
                              var xmlDoc=parser.parseFromString(str,"text/xml");
                            }
                            xmlObj=xmlDoc.documentElement;
                            var itemid=xmlObj.getElementsByTagName("item")[0].childNodes[0].nodeValue;
                            var size=xmlObj.getElementsByTagName("size")[0].childNodes[0].nodeValue;
                            /*########### End XML Parser ############*/
                            for an array in xml you do something like
                            Code:
                            <xml>
                              <city>somewhere1</city>
                              <city>somewhere2</city>
                              <city>somewhere3</city>
                              <city>somewhere4</city>
                            </xml>
                            then you use getElementsByTa gName("city").. this will return an array of elements... tiny example
                            Code:
                            var cities=getElementsByTagName("city");
                            for (var i=0; i<cities.length; i++) {
                              alert(cities[i].childNodes[0].nodeValue);
                            }
                            That will go through each "city" and alert the value.

                            Comment

                            • mikek12004
                              New Member
                              • Sep 2008
                              • 200

                              #15
                              I tried freddieMaize's solution and it worked (almost), it works both on IE and Firefox but in the city select box always the last option do not return any result, the selectcity.js is now
                              Code:
                              var xmlHttp 
                              
                              function showcity(str)
                              { 
                              	xmlHttp=GetXmlHttpObject()
                              	if (xmlHttp==null)
                              	{
                              		 alert ("Browser does not support HTTP Request")
                              		 return
                                  }
                              	
                              	var url="getcity.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 || xmlHttp.readyState=="complete")
                              	{ 
                               		//document.getElementById("city").innerHTML=xmlHttp.responseText 
                               		//try replacing-that failed try delimited approach
                              		  if(xmlHttp.readyState==4){
                              						status_name = xmlHttp.responseText;
                              						if ((status_name=="") || (status_name==null))
                              							{
                              								removeOptionLast2();
                              							}
                              							else
                              								{
                              									removeOptionLast2();
                              									var col_array1=status_name.split("/");
                              									var part_num1=0;
                              									while (part_num1 < col_array1.length)
                              										{
                              											var a=document.createElement('option');
                              											a.text=col_array1[part_num1];
                              											a.value=col_array1[part_num1];
                              											var b=document.getElementById("city");
                              											try
                              											{
                              												b.add(a,null); // standards compliant
                              											}
                              											catch(ex)
                              											{
                              												b.add(a); // IE only
                              											}                        
                              											part_num1+=1;
                              										}        
                              									}       
                              								}
                              	
                              	} 
                              }
                              
                              function removeOptionLast2(){
                                                          var i;
                                                          var remove_status_name = document.getElementById('city');
                                                          for(i=remove_status_name.length; i>=0; i--){
                                                              remove_status_name.remove(i);
                                                          }
                                                      }
                              
                              
                              function GetXmlHttpObject()
                              {
                              	var xmlHttp=null;
                              	try
                               	{
                               // Firefox, Opera 8.0+, Safari
                               		xmlHttp=new XMLHttpRequest();
                               	}
                              	catch (e)
                               	{
                               //Internet Explorer
                               		try
                                		{
                                			xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
                                		}
                               		
                              		catch (e)
                                		{
                                			xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
                                		}
                               	}
                              
                              	return xmlHttp;
                              }
                              and the getcity.php
                              Code:
                              <?php
                              include("./config.php");
                              $q=$_GET["q"];
                              $list="Any";
                              //echo  "<option value='A' selected='selected'>Any</option>";
                              $sql="SELECT DISTINCT city FROM models WHERE city!='' and country= '".$q."' ORDER BY city asc";
                              if ($q=="Any")
                              $sql="SELECT DISTINCT city FROM models WHERE city!='' ORDER BY city asc";
                              $result = mysql_query($sql);
                              while($lines=mysql_fetch_array($result))
                              {
                                 
                                 $list.="/".$lines[0];			
                              }
                              echo iconv("iso-8859-7","utf-8","$list");
                              
                              ?>
                              any idea?

                              Comment

                              Working...