Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Rhinorhino on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

dynamic select - how to keep other form data intact 1

Status
Not open for further replies.
Joined
Jul 28, 2005
Messages
358
Location
FR
Hi,

Hope this is the right forum for this one.

I have a form that has a couple of dynamic selects that pull in the relevant data for themselves form a mysql database (mix of javascript and php). These work no problems.

The problem I have, is that when ever the selects are changed and teh page refreshes to pull in the correct data for the next select then any other form data that has been input is lost.

Basically, the dynamic boxes are Country which when changed affects the contents of Region, which affects the contents of Town/city.

The user also has to input other info like title, description etc. (this is for a property rental website).

Is there an easy way to get (presumably) AJAX to control the popups so the page doesn't have to reload and lose the currently input data.

I am pretty hopeless at Javascript and haven't gone into AJAX at all, although I know it would probably be a good idea to get my head around it.

This is the code that is currently in place so you can see what I've done.

Javascript
Code:
function reload(form){
var val=form.country.options[form.country.options.selectedIndex].value;
self.location='index.php?country=' + val ;

}


function reloaded(form){
var val=form.country1.options[form.country1.options.selectedIndex].value;
self.location='index.php?country1=' + val ;

}
function reload1(form){
var val=form.country.options[form.country.options.selectedIndex].value;
self.location='addvilla.php?country=' + val ;

}


function reloaded1(form){
var val=form.region.options[form.region.options.selectedIndex].value;
var val1=form.country.options[form.country.options.selectedIndex].value;
self.location='addvilla.php?region=' + val + '&country=' + val1 ;

}

PHP for getting the relavant data from the database
Code:
///////// Getting the data from Mysql table for country list box//////////
$quer2=mysql_query("SELECT DISTINCT country_name,cid FROM country order by cid"); 
///////////// End of query for country list box////////////

/////// for region drop down list we will check if category is selected else we will display all the subcategory///// 
if(isset($country) and strlen($country) > 0){
$quer=mysql_query("SELECT DISTINCT region_name,rid FROM region where cid=$country order by region_name"); 
}else{$quer=mysql_query("SELECT DISTINCT region_name,rid FROM region order by region_name"); } 
////////// end of query for region subcategory drop down list box ///////////////////////////
/////// for Town drop down list we will check if category is selected else we will display all the subcategory///// 
if(isset($region) and strlen($region) > 0){
$quer3=mysql_query("SELECT DISTINCT town_name,tid FROM town where rid=$region order by town_name"); 
}else{$quer3=mysql_query("SELECT DISTINCT town_name FROM town order by town_name"); } 
////////// end of query for Town subcategory drop down list box ///////////////////////////

Form code
Code:
<form action="addvilla.php" method="post" enctype="multipart/form-data" name="form1" id="form1">
          <table width="613" border="0">
            <tr>
              <td height="-4" valign="top"><p>Villa Title</p></td>
              <td valign="top"><p>
                  <input name="title" type="text" id="title" />
              </p></td>
            </tr>
            <tr>
              <td height="-2" valign="top">Country</td>
              <td valign="top"><?
		  echo "<select name='country' onchange=\"reload1(this.form)\" class=\"formelements\"><option value='' >Country?</option>";
while($noticia2 = mysql_fetch_array($quer2)) { 
if($noticia2['cid']==@$country){echo "<option selected value='$noticia2[cid]'>$noticia2[country_name]</option>"."<BR>";}
else{echo  "<option value='$noticia2[cid]'>$noticia2[country_name]</option>";}
}
echo "</select>";
?></td>
            </tr>
            <tr>
              <td height="-2" valign="top">Or add a new Country </td>
              <td valign="top"><input name="newcountry" type="text" id="newcountry" /></td>
            </tr>
            <tr>
              <td height="-2" valign="top">Region</td>
              <td valign="top"><? echo "<select name='region' onchange=\"reloaded1(this.form)\" class=\"formelements\"><option value='' >Region?</option>";
while($noticia = mysql_fetch_array($quer)) { 
if($noticia['rid']==@$region){echo "<option selected value='$noticia[rid]'>$noticia[region_name]</option>"."<BR>";}
else{echo  "<option  value='$noticia[rid]'>$noticia[region_name]</option>";}
}
echo "</select>";
?> </td>
            </tr>
            <tr>
              <td height="-2" valign="top">Or add a new Region </td>
              <td valign="top"><input name="newregion" type="text" id="newregion" /></td>
            </tr>
            <tr>
              <td height="-2" valign="top">Town</td>
              <td valign="top"><label>
                <?
		  echo "<select name='town' class=\"formelements\"><option value=''>Town?</option>";
while($noticia3 = mysql_fetch_array($quer3)) { 
echo  "<option value='$noticia3[tid]'>$noticia3[town_name]</option>";
}
echo "</select>";
?>
              </label></td>
            </tr>
            <tr>
              <td height="-2" valign="top">Or Add a new Town </td>
              <td valign="top"><input name="newtown" type="text" id="newtown" /></td>
            </tr>
            <tr>
              <td height="-2" valign="top">ShortDescription: </td>
              <td valign="top"><input name="shortdesc" type="text" id="shortdesc" /></td>
            </tr>
            <tr>
              <td height="-2" valign="top">Departure date and time</td>
              <td valign="top"><input name="dep" type="text" id="dep" /></td>
            </tr>
            <tr>
              <td height="-2" valign="top">Arrival Date and Time</td>
              <td valign="top"><input name="arr" type="text" id="arr" /></td>
            </tr>
            <tr>
              <td height="34" valign="top"><input name="addprop" type="hidden" id="addprop" value="1" /></td>
              <td valign="top"><input type="submit" name="Submit" value="Continue" />
                  
                  </td>
            </tr>
          </table>
          <p>&nbsp;</p>
          <p>&nbsp;</p>
        </form>

Thanks,

Richard
 
There are a number of appoaches but here is what I suggest.

Since you are using server-side code to get the data to populate the select boxes just grab all of the data you need at one time and store it in arrays, then instead of refreshing the page every time a selection is made you can just call a javascript function to repopulate the select box with the appropriate options. This is the best approach because the page does not have to reload at all and you do not have to worry about persisting your data.
However, if you are not good with Javascript there is a lot to learn first about using arrays and dynamically rebuilding the select boxes.

Another approach would be to cause the form to SUBMIT, not just change the URL location when a selection is made. When it is submitted you can use your server side code to read all of the form values as they were when the selection was made and use those values to re-populate those fields. You can also read the selected values of the select fields so that you know which options to populate there as well.
This is the easiest way for you to go at this point but it does require the page to reload every time a selection in your dynamic select boxes is changed.


It's hard to think outside the box when I'm trapped in a cubicle.
 
Thanks niteowl.

I don't want to store all the info in an array like that because there are a hell of a lot of entries in the database so the array would be huge.

I am playing around with a script I found at which seems to do everything I want apart from the fact it's using hard coded options at the moment.
Now i just need to work out how to get it to use he results of a mysql query to display in the region.

I'm sure I'll get there eventually, but if anyone wants to have a look at the above link and suggest how to procede bearing my code above in mind that would be great.

Richard
 
This is quick and still incomplete but look over this code.
Code:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
  <title>Browse to and read a file</title>
<script type='text/javascript'>
<!--
function include(which) {
  if (document.all)  { // IE version
    try {
      var xml = new ActiveXObject("Microsoft.XMLHTTP");
      xml.Open( "GET", url, false );
      xml.Send()
      return xml.responseText;
    }
    catch (e) {
      var xml = new ActiveXObject("MSXML2.XMLHTTP.4.0");
      xml.Open( "GET", url, false );
      xml.Send()
      return xml.responseText;
    }
  }
  else { // Mozilla/Netscape 6+ version
    var xml=new XMLHttpRequest();
    xml.open("GET",url,false);
    xml.send(null);
    return xml.responseText;
  }
}

function updateOptions(which) {
  var selval = which.options[which.options.selectedIndex].value;
  var url = 'regioninfo.php?' + which.name + '=' + selval;
  var optionlist = include(url);
  rebuildOptions(which, optionlist);
}

function rebuildOptions(which, options) {
  //Not written yet.
}
//-->
</script>
</head>
<body>
<select name='region' onchange="updateOptions(this)" class="formelements">
  <option value='' >Region?</option>
  <option value='one' >One</option>
  <option value='two' >Two</option>
</select><br>
<select name='country' onchange="updateOptions(this)" class="formelements">
  <option value='' >Country?</option>
  <option value='us' >US</option>
  <option value='canada' >Canada</option>
</select>
</body>
</html>

This does essentially what you want up to a point.
If a change occurs in either option list it calls the updateOptions function passing a reference to the option list that called it.
The updateOptions function builds a URL based on a filename I made up called regioninfo.php and then appends a parameter named after the select box that called it and the value is the value of the selected option. This way you only need one function to handle each select box.
The function then passes the constructed URL to the include function which will execute the file regioninfo.php (which does not yet exist) and pass in the parameter named after the select box and the value of it's current selection.
The regioninfo.php file will do it's processing and return a text string that will be set into the variable optionlist in the updateOptions function.

You still need two things, a regioninfo.php file and a function to repopulate the options list.
The regioninfo.php file should test the URL to see which parameter name was passed and it's value so it can execute the appropriate SQL query. The output of the query should be a single delimeted string, probably just seperated by commas.
Then in the rebuildOptions function you already have the object passed in under the value which so you know which select box to alter and you have a delimited string containing all the values to populate.

I may be able to help with the dynamic rebuilding of the options list in a bit, just have not gotten to it yet. But you will first need to write the PHP code to return the data.


It's hard to think outside the box when I'm trapped in a cubicle.
 
Thanks loads niteowl for your hard work trying to help me on this.

I have just sorted it out using the dhtml goodies script I linked to earlier.
It's probably not the prettiest code, but I can always go back to it later on if need be.

I'll post it in a bit when I have got it working in the pages I want so it makes a bit more sense.

Again thanks, I think I am going to need to get a grip on Javascript and AJAX as I can see me using them a fair bit.

Richard
 
My code might be cleaner for you to use than blending the other code.

There is one bug in my code. It changes the same select box that the change occured in. You really want it to change the next dependent box. That is as simple as passing the name of the box you want changed in the function call and using that instead of which within the functions.

If the other code is working for you that's good. I think my approach is a bit clearer to understand and easier for you to re-use later though. If you walk away from this for a month or two and come back to make changes you might have to figure it out all over again.

The include function in my code above can be used for any type of file not just PHP. You can use it to read a text file, HTML, ASP, etc. It just returns the results of the output of the page read to the variable.

Here is the function to rebuild the option list.
Code:
function rebuildOptions(which, options) {
  //Break options string into array.
  var arrOptions = options.split(',');
  //Remote existing options.
  which.options.length = 0;
  //Insert new options
  for (var i=0;i<arrOptions.length;i++ ) {
    which.options[i] = new Option(arrOptions[i], arrOptions[i]);
  }
}


It's hard to think outside the box when I'm trapped in a cubicle.
 
Right, apromised, here is the code I have come up with. Thanks to niteowl for helping and also dhtmlgoodies.com for the code!

First, the javascript that is in the head of my page. - I have had to duplicate the functions a little to deal with the two dependant boxes that are needed. There may be a way to get around this

Code:
<script type="text/javascript" src="../js/ajax.js"></script>
<script type="text/javascript">
/************************************************************************************************************
(C) [URL unfurl="true"]www.dhtmlgoodies.com,[/URL] October 2005

This is a script from [URL unfurl="true"]www.dhtmlgoodies.com.[/URL] You will find this and a lot of other scripts at our website.	

Terms of use:
You are free to use this script as long as the copyright message is kept intact. However, you may not
redistribute, sell or repost it without our permission.

Thank you!

[URL unfurl="true"]www.dhtmlgoodies.com[/URL]
Alf Magne Kalleland

************************************************************************************************************/	
var ajax = new sack();

function getCityList(sel)
{
	var countryCode = sel.options[sel.selectedIndex].value;
	document.getElementById('dhtmlgoodies_city').options.length = 0;	// Empty city select box
	if(countryCode.length>0){
		ajax.requestFile = 'getCities.php?countryCode='+countryCode;	// Specifying which file to get
		ajax.onCompletion = createCities;	// Specify function that will be executed after file has been found
		ajax.runAJAX();		// Execute AJAX function
	}
}

function createCities()
{
	var obj = document.getElementById('dhtmlgoodies_city');
	eval(ajax.response);	// Executing the response from Ajax as Javascript code	
}

function getCityList1(sel)
{
	var regionCode = sel.options[sel.selectedIndex].value;
	document.getElementById('dhtmlgoodies_city1').options.length = 0;	// Empty city select box
	if(regionCode.length>0){
		ajax.requestFile = 'getCities1.php?regionCode='+regionCode;	// Specifying which file to get
		ajax.onCompletion = createCities1;	// Specify function that will be executed after file has been found
		ajax.runAJAX();		// Execute AJAX function
	}
}

function createCities1()
{
	var obj = document.getElementById('dhtmlgoodies_city1');
	eval(ajax.response);	// Executing the response from Ajax as Javascript code	
}

		
</script>

Tha javascript file that is called can de downloaded from
Put it in a folder and change the reference in the code above to point to it.

The form code
Code:
<table width="613" border="0">
            <tr>
              <td height="-4" valign="top"><p>Villa Title</p></td>
              <td valign="top"><p>
                  <input name="title" type="text" id="title" class="formelements"/>
              </p></td>
            </tr>
            <tr>
              <td height="-2" valign="top">Country</td>
              <td valign="top"><select id="dhtmlgoodies_country" name="dhtmlgoodies_country" class="formelements" onchange="getCityList(this)">
		<option>Select Country</option>
			
		<?		
		$quer2=mysql_query("SELECT DISTINCT country_name,cid FROM country order by cid"); 
		while($result=mysql_fetch_array($quer2)) { 
		
			echo  "<option value='$result[cid]'>$result[country_name]</option>";
			}
			?>
		      </select></td>
            </tr>
            <tr>
              <td height="-2" valign="top">Or add a new Country </td>
              <td valign="top"><input name="newcountry" type="text" id="newcountry" class="formelements"/></td>
            </tr>
            <tr>
              <td height="-2" valign="top">Region</td>
              <td valign="top"><select id="dhtmlgoodies_city" name="dhtmlgoodies_city" class="formelements" onchange="getCityList1(this)">
                <option>Select Region</option>
                            </select></td>
            </tr>
            <tr>
              <td height="-2" valign="top">Or add a new Region </td>
              <td valign="top"><input name="newregion" type="text" id="newregion" class="formelements"/></td>
            </tr>
            <tr>
              <td height="-2" valign="top">Town</td>
              <td valign="top"><label>
                <select id="dhtmlgoodies_city1" name="dhtmlgoodies_city1" class="formelements">
                  <option>Select City/Town</option>
                                </select>
              </label></td>
            </tr>
            <tr>
              <td height="-2" valign="top">Or Add a new Town </td>
              <td valign="top"><input name="newtown" type="text" id="newtown" class="formelements"/></td>
            </tr>
            <tr>
              <td height="-2" valign="top">Short Description: </td>
              <td valign="top"><textarea name="shortdesc"  rows="4" class="formelements"></textarea></td>
            </tr>
            <tr>
              <td height="-2" valign="top">Departure Day and Time</td>
              <td valign="top"><input name="dep" type="text" id="dep" class="formelements"/></td>
            </tr>
            <tr>
              <td height="-2" valign="top">Arrival Day and Time</td>
              <td valign="top"><input name="arr" type="text" id="arr" class="formelements"/></td>
            </tr>
            <tr>
              <td height="34" valign="top"><input name="addprop" type="hidden" id="addprop" value="1" /></td>
              <td valign="top"><input type="submit" name="Submit" value="Continue" />              </td>
            </tr>
          </table>

And lastly, the two php files that get the data from the database.
getCities.php
Code:
<?php
include ('../headerfooter/conf.php');
if(isset($_GET['countryCode'])){
$country = $_GET['countryCode'];
//$country=1;
//echo $country;
  
  //switch($_GET['countryCode']){
    echo "obj.options[obj.options.length] = new Option('Select Region','');\n";
    $sql=mysql_query("SELECT DISTINCT region_name,rid FROM region where cid=$country order by region_name");	
	while ($result = mysql_fetch_array($sql)){	
	

	echo "obj.options[obj.options.length] = new Option('";
	echo  $result['region_name']; 
	echo "','";
	echo $result['rid'];
	echo  "');\n";
	      //echo "obj.options[obj.options.length] = new Option('Aalborg','11');\n";   
  }  
}
//}

?>

getCities1.php

Code:
<?php
include ('../headerfooter/conf.php');
if(isset($_GET['regionCode'])){
$region = $_GET['regionCode'];

    echo "obj.options[obj.options.length] = new Option('Select City/Town','');\n";
    $sql=mysql_query("SELECT DISTINCT town_name,tid FROM town where rid=$region order by town_name");	
	while ($result = mysql_fetch_array($sql)){	
	

	echo "obj.options[obj.options.length] = new Option('";
	echo  $result['town_name']; 
	echo "','";
	echo $result['tid'];
	echo  "');\n";
	      
  }  
}


?>

Think that's all, it seems to work exactly how I want. If anyone has any ideas on how to reduce the code, then please let me know. I'm pleased with the overall effect though.

Richard
 
Thanks again Niteowl.

For the moment I think I'll probably stick with what I have got. Luckily, I always document straight after something is working so I should be OK if I want to do anything with it in the future. Good of you to think about it though.

I like the idea of your code too, and may decide to change to it later. Unfortunately I have a pretty tight deadline on this one so I'll leave it for now as it does what I want for the moment. I can always change it afterwards if need be.

Richard
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top