Zur Navigation

AJAX-Script erweitern

1 Andreas (Gast)

Hallo zusammen,
ich bin ich in Sachen AJAX absoluter Frischling und stehe vor dem für mich aktuell noch unlösbaren Problem ein ajax Script zu erweitern.

Diese Script bewirkt, dass in drei DropDown-Feldern (Land/Staat/Stadt) der jeweils passende Datensatz anchgeladen wird (also bei Deutschland-> Bayern eben alle Städte in Bayern). Nun muss dieses Script um eine "Ebene" tiefer namens "Universitäten" erweitert werden und ich habe absolut keine Ahnung wie ich das machen soll.Die SQL-Funktion kriege ich hin.

Anbei das Script. Ist sicherlich für ajax-Profis kein Problem. :)

<script language="JavaScript">
<!--
function HS_StatesPopulate(FormHandler,AllowEmpty)
{
   for(var k = FormHandler.student_state.options.length-1; k>=0; k--)
   {
      FormHandler.student_state.options[k] = null;
   }//for
   for(var k = FormHandler.student_city.options.length-1; k>=0; k--)
   {
      FormHandler.student_city.options[k] = null;
   }//for
   FormHandler.student_state.options[0] = new Option("...Daten werden geladen...");
   FormHandler.student_city.options[0] = new Option("...Daten werden geladen...");
   var Country = FormHandler.student_country.options[FormHandler.student_country.selectedIndex].value;
   var xmlHttpReq = false;
   var self = this;
   // Mozilla/Safari
   if (window.XMLHttpRequest)
   {
      self.xmlHttpReq = new XMLHttpRequest();
   }//if
   // IE
   else if (window.ActiveXObject)
   {
      self.xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
   }//else if
   self.xmlHttpReq.open('POST', "index.php", true);
   self.xmlHttpReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
   self.xmlHttpReq.onreadystatechange = function()
   {
      if (self.xmlHttpReq.readyState == 4 && self.xmlHttpReq.status == 200)
      {
         HS_PullData(self.xmlHttpReq.responseXML,FormHandler.student_state,'state');
         HS_PullData(self.xmlHttpReq.responseXML,FormHandler.student_city,'city');
      }//if
   }//function
   self.xmlHttpReq.send("handler=geo&action=states&country="+Country+"&allow_empty="+AllowEmpty);
}//HS_StatesPopulate

function HS_CitiesPopulate(FormHandler,AllowEmpty)
{
   for(var k = FormHandler.student_city.options.length-1; k>=0; k--)
   {
      FormHandler.student_city.options[k] = null;
   }//for
   FormHandler.student_city.options[0] = new Option("...Daten werden geladen...");
   var Country = FormHandler.student_country.options[FormHandler.student_country.selectedIndex].value;
   var State = FormHandler.student_state.options[FormHandler.student_state.selectedIndex].value;
   var xmlHttpReq = false;
   var self = this;
   // Mozilla/Safari
   if (window.XMLHttpRequest)
   {
      self.xmlHttpReq = new XMLHttpRequest();
   }//if
   // IE
   else if (window.ActiveXObject)
   {
      self.xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
   }//else if
   self.xmlHttpReq.open('POST', "index.php", true);
   self.xmlHttpReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
   self.xmlHttpReq.onreadystatechange = function()
   {
      if (self.xmlHttpReq.readyState == 4 && self.xmlHttpReq.status == 200)
      {
         HS_PullData(self.xmlHttpReq.responseXML,FormHandler.student_city,'city');
      }//if
   }//function
   self.xmlHttpReq.send("handler=geo&action=cities&&country="+Country+"&state="+State+"&allow_empty="+AllowEmpty);
}//HS_CitiesPopulate

function HS_PullData(XMLData,FieldHandler,ItemName)
{
   for(var k = FieldHandler.options.length-1; k>=0; k--)
   {
      FieldHandler.options[k] = null;
   }//for
   var Items = XMLData.getElementsByTagName(ItemName);
   for(var i=0;i<Items.length;i++)
   {
      var ItemID = Items[i].firstChild.firstChild.nodeValue;
      var ItemName = Items[i].firstChild.nextSibling.firstChild.nodeValue;
      FieldHandler.options[i] = new Option(ItemName,ItemID);
   }//for
}//HS_PullData
//-->
</script>

31.10.2009 02:59

2 Jörg

Du hast da zwei Funktionen, die jeweils einen Request absenden; die Parameter, die HS_StatesPopulate() an die index.php versendet, werden z.B. hier definiert:

self.xmlHttpReq.send("handler=geo&action=states&country="+Country+"&allow_empty="+AllowEmpty);

HS_CitiesPopulate() ist um einen weiteren Parameter "State" erweitert. Nach diesem Muster kannst du eine dritte Funktion mit dem Parameter "action=universities" erstellen, die um noch einen Parameter für die Universitäten erweitert ist. In der index.php wertest du diesen zusätzlichen Parameter dann entsprechend aus

Die Parameter müssen im Script noch auch aus dem betreffenden Formularfeld geholt werden, wie z.B. der Parameter "Country" aus dem Auswahlmenu "student_country":

   var Country = FormHandler.student_country.options[FormHandler.student_country.selectedIndex].value;

Ich kenne den HTML-Code des Formulars nicht - analog zu den beiden anderen Funktionen muss die neue Funktion dann noch an passender Stelle aufgerufen werden.

31.10.2009 09:25 | geändert: 31.10.2009 09:29

3 Andreas (Gast)

okay.. soweit kapiert. Ich habe es sogar geschafft, dass das Dropdownfeld jetzt angezeigt wird und er beim Ändern des Landes, Bundeslandes und der Stadt auch auf dieses Feld "irgendwie" zugreift. Leider läd er allerdings - egal was ich auswähle - keine Daten in das Dropdown-Feld rein.

Der Fehler liegt daran, dass die Variable $city im case 'unis' leer ist (wurde mir per echo bestätigt) und somit die SQL-Abfrage nicht ausführt wird. Warum $city leer ist ist mir völlig schleierhaft. Ich glaube ich sehe gerade den Wald vor lauter Bäumen nicht.

case 'countries':
	$options = array();

	if(!$value)
		$value = "";

	if($dets[1])
		$options[0] = $GLOBALS["language"]["please_select"];
	else
		$dets[1] = 0;
	$sql_query = "SELECT * FROM geo_countries ORDER BY name";
	$result = $GLOBALS["DB"]->result($sql_query);
	foreach($result as $res){
		$options[$res["con_id"]] = $res["name"];
	}//foreach
	$default = $dets[0];
	if(empty($value))
		$country = $default;
	else
		$country = $value;
		$output = build_options_list($name,$options,$value,$default,0,"style='width:180px;' onChange='HS_StatesPopulate(this.form,".$dets[1].")'");
	break;

case 'states':
	$options = array();
	if(!$value)
		$value = "";
	if($dets[0])
		$options[0] = $GLOBALS["language"]["please_select"];
	else
		$dets[0] = 0;
	if(empty($country) && $dets[1])
		$country = $dets[1];

	if($country){
		$sql_query = "SELECT * FROM geo_states WHERE con_id=".$country." ORDER BY name";
		$result = $GLOBALS["DB"]->result($sql_query);

		if(!$dets[0])
			$first = 1;

		foreach($result as $res){
			if($first){
				$default = $res["sta_id"];
				$first = 0;
			}//if
			$options[$res["sta_id"]] = $res["name"];
		}//foreach

		if($value && !array_key_exists($value,$options))
			$value = 0;

		if(empty($value))
			$state = $default;
		else
			$state = $value;
		}//if
		$output = build_options_list($name,$options,$value,$default,0,"style='width:180px;' onChange='HS_CitiesPopulate(this.form,".$dets[0].")'");
		break;

case 'cities':
		$options = array();

		if(!$value)
			$value = "";

		if($dets[0])
			$options[0] = $GLOBALS["language"]["please_select"];
		else
			$dets[0] = 0;

		if(empty($state) && $dets[1])
			$state = $dets[1];

		if($state){
			$sql_query = "SELECT * FROM geo_cities WHERE con_id=".$country." AND sta_id=".$state." ORDER BY name";
			$result = $GLOBALS["DB"]->result($sql_query);

		if(!$dets[0])
			$first = 1;

		foreach($result as $res){
			if($first){
				$default = $res["cty_id"];
				$first = 0;
			}//if
			$options[$res["cty_id"]] = $res["name"];
		}//foreach

		if($value && !array_key_exists($value,$options))
			$value = 0;

		if(empty($value))
			$city = $default;
		else
			$city = $value;
		}//if
		$output = build_options_list($name,$options,$value,0,0,"style='width:180px;' onChange='HS_UnisPopulate(this.form,".$dets[0].")'");
		break;

case 'unis':
		$options = array();

		if(!$value)
			$value = "";

		if($dets[0])
			$options[0] = $GLOBALS["language"]["please_select"];

		if($city){
			$sql_query = "SELECT * FROM geo_unis WHERE con_id=".$country." AND sta_id=".$state." AND cty_id=".$city." ORDER BY name";
			$result = $GLOBALS["DB"]->result($sql_query);
			foreach($result as $res){
				$options[$res["uni_id"]] = $res["name"];
			}//foreach
		}//if
		$output = build_options_list($name,$options,$value,0,0,"style='width:180px;'");
		break;

Mein um die Uni-Funktion erweitertes JS sieht so aus:

function HS_StatesPopulate(FormHandler,AllowEmpty)
{
   for(var k = FormHandler.student_state.options.length-1; k>=0; k--)
   {
      FormHandler.student_state.options[k] = null;
   }//for
   for(var k = FormHandler.student_city.options.length-1; k>=0; k--)
   {
      FormHandler.student_city.options[k] = null;
   }//for
   FormHandler.student_state.options[0] = new Option("...Daten werden geladen...");
   FormHandler.student_city.options[0] = new Option("...Daten werden geladen...");
   FormHandler.student_uni.options[0] = new Option("...Daten werden geladen...");
   var Country = FormHandler.student_country.options[FormHandler.student_country.selectedIndex].value;
   var xmlHttpReq = false;
   var self = this;
   // Mozilla/Safari
   if (window.XMLHttpRequest)
   {
      self.xmlHttpReq = new XMLHttpRequest();
   }//if
   // IE
   else if (window.ActiveXObject)
   {
      self.xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
   }//else if
   self.xmlHttpReq.open('POST', "index.php", true);
   self.xmlHttpReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
   self.xmlHttpReq.onreadystatechange = function()
   {
      if (self.xmlHttpReq.readyState == 4 && self.xmlHttpReq.status == 200)
      {
         HS_PullData(self.xmlHttpReq.responseXML,FormHandler.student_state,'state');
         HS_PullData(self.xmlHttpReq.responseXML,FormHandler.student_city,'city');
         HS_PullData(self.xmlHttpReq.responseXML,FormHandler.student_uni,'uni');
      }//if
   }//function
   self.xmlHttpReq.send("handler=geo&action=states&country="+Country+"&allow_empty="+AllowEmpty);
}//HS_StatesPopulate

function HS_CitiesPopulate(FormHandler,AllowEmpty)
{
   for(var k = FormHandler.student_city.options.length-1; k>=0; k--)
   {
      FormHandler.student_city.options[k] = null;
   }//for
   FormHandler.student_city.options[0] = new Option("...Daten werden geladen...");
   FormHandler.student_uni.options[0] = new Option("...Daten werden geladen...");
   var Country = FormHandler.student_country.options[FormHandler.student_country.selectedIndex].value;
   var State = FormHandler.student_state.options[FormHandler.student_state.selectedIndex].value;
   var xmlHttpReq = false;
   var self = this;
   // Mozilla/Safari
   if (window.XMLHttpRequest)
   {
      self.xmlHttpReq = new XMLHttpRequest();
   }//if
   // IE
   else if (window.ActiveXObject)
   {
      self.xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
   }//else if
   self.xmlHttpReq.open('POST', "index.php", true);
   self.xmlHttpReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
   self.xmlHttpReq.onreadystatechange = function()
   {
      if (self.xmlHttpReq.readyState == 4 && self.xmlHttpReq.status == 200)
      {
         HS_PullData(self.xmlHttpReq.responseXML,FormHandler.student_city,'city');
         HS_PullData(self.xmlHttpReq.responseXML,FormHandler.student_uni,'uni');
      }//if
   }//function
   self.xmlHttpReq.send("handler=geo&action=cities&&country="+Country+"&state="+State+"&allow_empty="+AllowEmpty);
}//HS_CitiesPopulate

function HS_UnisPopulate(FormHandler,AllowEmpty)
{
   for(var k = FormHandler.student_uni.options.length-1; k>=0; k--)
   {
      FormHandler.student_uni.options[k] = null;
   }//for
   FormHandler.student_uni.options[0] = new Option("...Daten werden geladen...");
   var Country = FormHandler.student_country.options[FormHandler.student_country.selectedIndex].value;
   var State = FormHandler.student_state.options[FormHandler.student_state.selectedIndex].value;
   var Uni = FormHandler.student_uni.options[FormHandler.student_uni.selectedIndex].value;
   var xmlHttpReq = false;
   var self = this;
   // Mozilla/Safari
   if (window.XMLHttpRequest)
   {
      self.xmlHttpReq = new XMLHttpRequest();
   }//if
   // IE
   else if (window.ActiveXObject)
   {
      self.xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
   }//else if
   self.xmlHttpReq.open('POST', "index.php", true);
   self.xmlHttpReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
   self.xmlHttpReq.onreadystatechange = function()
   {
      if (self.xmlHttpReq.readyState == 4 && self.xmlHttpReq.status == 200)
      {
         HS_PullData(self.xmlHttpReq.responseXML,FormHandler.student_uni,'uni');
      }//if
   }//function
   self.xmlHttpReq.send("handler=geo&action=unis&&country="+Country+"&state="+State+"&uni="+Uni+"&allow_empty="+AllowEmpty);
}//HS_CitiesPopulate

function HS_PullData(XMLData,FieldHandler,ItemName)
{
   for(var k = FieldHandler.options.length-1; k>=0; k--)
   {
      FieldHandler.options[k] = null;
   }//for
   var Items = XMLData.getElementsByTagName(ItemName);
   for(var i=0;i<Items.length;i++)
   {
      var ItemID = Items[i].firstChild.firstChild.nodeValue;
      var ItemName = Items[i].firstChild.nextSibling.firstChild.nodeValue;
      FieldHandler.options[i] = new Option(ItemName,ItemID);
   }//for
}//HS_PullData

Die etwas gekürzte Ausgabe im Formular sieht so aus:

<form action="index.php" method="post" enctype="multipart/form-data" name="join_step2">
	<div class="field">
		<label>Ich studiere</label>		
		<select class="dropdown" name="student_studium"  >
			<option value="" selected>Please, select...</option>
			<option value="1">Student/in der Humanmedizin</option>
			<option value="2">Student/in der Tiermedizin</option>
			<option value="3">Student/in der Zahnmedizin</option>
		</select>
	</div>
	<div class="field">
		<label>Land der Universität</label>		
		<select class="dropdown" name="student_country" style='width:180px;' onChange='HS_StatesPopulate(this.form,0)' >
			<option value="157">Afghanistan</option>
			<option value="141">Ägypten</option>
			<option value="176">Albanien</option>
		</select>
	</div>
	<div class="field">
		<label>Bundesland der Universität</label>		
		<select class="dropdown" name="student_state" style='width:180px;' onChange='HS_CitiesPopulate(this.form,0)' >
			<option value="3435" selected>Alabama</option>
			<option value="3479">Alaska</option>
			<option value="3471">American Samoa</option>
		</select>
	</div>
	<div class="field">
		<label>Stadt der Universität</label>		
		<select class="dropdown" name="student_city" style='width:180px;' onChange='HS_UnisPopulate(this.form,0)' >
			<option value="124807">Abbeville</option>
			<option value="124515">Abernant</option>
			<option value="124411">Adamsville</option>
		</select>
	</div>
	<div class="field">
		<label>Universität</label>		
		<select class="dropdown" name="student_uni" style='width:180px;' ></select>
	</div>
</form>

15.11.2009 02:53

4 Jörg

Du hast bei "case 'states':" so etwas stehen:
	if(empty($country) && $dets[1])
		$country = $dets[1];

... und bei "case 'cities':":
		if(empty($state) && $dets[1])
			$state = $dets[1];

Bei "case 'unis':" benötigst du vermutlich noch eine analoge Zuordnung:
		if(empty($city) && $dets[1])
			$city = $dets[1];

15.11.2009 23:57

5 Andreas (Gast)

Hallo Jörg,

ich habe die Funktion nach deinen Angaben modifiziert. Hat leider keine Wirkung gezeigt. Das kann doch echt nicht so schwer sein. :-(

case 'countries':
	$options = array();

	if(!$value)
		$value = "";

	if($dets[1])
		$options[0] = $GLOBALS["language"]["please_select"];
	else
		$dets[1] = 0;
	$sql_query = "SELECT * FROM geo_countries ORDER BY name";
	$result = $GLOBALS["DB"]->result($sql_query);
	foreach($result as $res)
	{
		$options[$res["con_id"]] = $res["name"];
	}//foreach
	$default = $dets[0];
	if(empty($value))
		$country = $default;
	else
		$country = $value;
	$output = build_options_list($name,$options,$value,$default,0,"style='width:180px;' onChange='HS_StatesPopulate(this.form,".$dets[1].")'");
	break;

case 'states':
	$options = array();

	if(!$value)
		$value = "";

	if($dets[0])
		$options[0] = $GLOBALS["language"]["please_select"];
	else
		$dets[0] = 0;

	if(empty($country) && $dets[1])
		$country = $dets[1];

	if($country)
	{
		$sql_query = "SELECT * FROM geo_states WHERE con_id=".$country." ORDER BY name";
		$result = $GLOBALS["DB"]->result($sql_query);

		if(!$dets[0])
			$first = 1;

		foreach($result as $res)
		{
			if($first)
			{
				$default = $res["sta_id"];
				$first = 0;
			}//if
			$options[$res["sta_id"]] = $res["name"];
		}//foreach

		if($value && !array_key_exists($value,$options))
			$value = 0;

		if(empty($value))
			$state = $default;
		else
			$state = $value;
	}//if
	$output = build_options_list($name,$options,$value,$default,0,"style='width:180px;' onChange='HS_CitiesPopulate(this.form,".$dets[0].")'");
	break;

case 'cities':
	$options = array();

	if(!$value)
		$value = "";

	if($dets[0])
		$options[0] = $GLOBALS["language"]["please_select"];
	else
		$dets[0] = 0;

	if(empty($state) && $dets[1])
		$state = $dets[1];

	if($state)
	{
		$sql_query = "SELECT * FROM geo_cities WHERE con_id=".$country." AND sta_id=".$state." ORDER BY name";
		$result = $GLOBALS["DB"]->result($sql_query);

		if(!$dets[0])
			$first = 1;

		foreach($result as $res)
		{
			if($first)
			{
				$default = $res["cty_id"];
				$first = 0;
			}//if
			$options[$res["cty_id"]] = $res["name"];
		}//foreach

		if($value && !array_key_exists($value,$options))
			$value = 0;

		if(empty($value))
			$city = $default;
		else
			$city = $value;
	}//if
	$output = build_options_list($name,$options,$value,0,0,"style='width:180px;' onChange='HS_UnisPopulate(this.form,".$dets[0].")'");
	break;

case 'unis':
	$options = array();

	if(!$value)
		$value = "";

	if($dets[0])
		$options[0] = $GLOBALS["language"]["please_select"];

	if(empty($city) && $dets[1])
		$city = $dets[1];

	if($city)
	{
		$sql_query = "SELECT * FROM geo_unis WHERE con_id=".$country." AND sta_id=".$state." AND cty_id=".$city." ORDER BY name";
		$result = $GLOBALS["DB"]->result($sql_query);
		foreach($result as $res)
		{
			$options[$res["uni_id"]] = $res["name"];
		}//foreach
	}//if
	$output = build_options_list($name,$options,$value,0,0,"style='width:180px;'");
	break;

16.11.2009 05:17

6 Andreas (Gast)

Sorry für den Doppelpost. Ich habe noch etwas festgestellt:

Wenn ich im case 'uni' direkt vor der if($city) Abfrage der $city testweise die ID einer Stadt zuweise (z.B. $city = 74433;) funktioniert es und er gibt mir die Unis der Stadt mit der ID 74433 aus. Es liegt also offenbar wirklich daran, dass er die $city irgendwo verliert oder erst gar nicht erst mit der ID der aktuell ausgewählten Stadt füllt.

16.11.2009 05:29

7 Jörg

Hängt vielleicht davon ab, wie das Array $dets definiert ist?

16.11.2009 08:28

8 Andreas (Gast)

Hallo Jörg,

ja in dem $dets-Array steht die jeweilige ID drin die übergeben werden soll. Also bei countrys die ID des ausgewählten States bei states die ID der gewählten Stadt, usw.

Komischerweise gibt es bei countrys $dets[0] und $dets[1]. Bei den Staats, Citys und Unis gibt es nur noch $dets[0].

Hilft mir zugegebenermaßen nicht sonderlich weiter.

17.11.2009 03:08

Beitrag schreiben (als Gast)





[BBCode-Hilfe]