Link to home
Start Free TrialLog in
Avatar of Vanq69
Vanq69

asked on

Passing Variable Number of Variables through AJAX

Hi,

I have a page which creates check boxes using entries from the database.  This means I can have 1 check box or say 10 - value wont be higher than 10 most likely.

I want to call an AJAX method to pass these through to the server in order to perform a query using the selected checkboxes - i have no need for the others.

How can I get these values for the AJAX and pass them through?  Is it possible to calculate the length of the form and do a loop of some kind?  I have attached the code I have so far.


HTML:
 
<form id="amenOptions">
	<?php
		include("amenOptions.php");
	?>
</form>
 
PHP file:
 
$result = mysql_query("SELECT * FROM amen " . " ORDER BY amenname ASC");
$countResults = mysql_numrows($result);
	
for($i=0; $i<$countResults; $i++)
{
	echo '<input type="checkbox" id="'.mysql_result($result,$i,"amenid").'" value=""'.mysql_result($result,$i,"amenname").'">';
	echo "   " . mysql_result($result,$i,"amenname");
	echo "<br />";
	echo "<br />";
}
 
AJAX so far:
 
function hotelSearch()
{
  if (xmlHttp)
  {
    params = "";
	
	var drop = document.getElementById('citiesDrop');
	var city = drop.options[drop.selectedIndex].value;
	
	// other values....
	
	if (city)
   	{
		params = "city=" + city + ; // other values....
		
		if (params) cache.push(params);
		try
		{
		  // only continue if the connection is clear and cache is not empty
		  if ((xmlHttp.readyState == 4 || xmlHttp.readyState == 0) && cache.length>0)
		  {
			// get next set of values from cache
			var cacheEntry = cache.shift();
	
			xmlHttp.open("POST", "hotelSearch.php", true);
			xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
			xmlHttp.setRequestHeader("Content-length", params.length);
			xmlHttp.setRequestHeader("Connection", "close");
			xmlHttp.onreadystatechange = executeHotelSearchChange;
			xmlHttp.send(cacheEntry);
		  }
		  else
		  {
			setTimeout("hotelSearch();", 1000);  
		  }
		}
		
		catch (e)
		{
		  displayError(e.toString());
		}
	}
		
	else
	{
		alert("Please select a City');
	}
  }
}
 
hotelSearch.php
 
<?php
	$city = $_POST['city']; 
	// other values needed here
?>

Open in new window

Avatar of bugada
bugada
Flag of Italy image

Yes just do a loop like that :
var form = getElementById("amenOptions");
for (var i=0; i< form.elements.length; i++) {
   var elem = form.elements[i];
   
   // We check the element type, in case there are other object in the form.
   if (elem.type == "checkbox") {
     // collect here values using elem.value, elem.checked, elem.id ect
   }
}

Open in new window

Avatar of Vanq69
Vanq69

ASKER

Thanks, how do I then add them to the params string as well as retrieve them in the php file using $_POST
you can use a for to contruct the query string needed for ajax
they need to have the same name so they get into an array.

see example below ..
the ajax variables could be contructed with something like this:

var urlvar= '';
for ( var i in document.forms['asd'].elements['asd[]'] )
{
     if (document.forms['asd'].elements['asd[]'][i].checked)
    {
         urlvar += document.forms['asd'].elements['asd[]'][i].value;
    }
}
<form name="asd">
<input type="checkbox" name="asd[]">
<input type="checkbox" name="asd[]" value="er">
<input type="checkbox" name="asd[]">
</form>
 
<script>
 
alert('Nr elements:'+document.forms['asd'].elements['asd[]'].length);
alert('Value of 2nd checkbox '+document.forms['asd'].elements['asd[]'][1].value);
 
</script>

Open in new window

Avatar of Vanq69

ASKER

I have build from Bugada and constructed what is in the code.

I am having 2 issues.  Firstly the JavaScript wont accept:
form.elements.length

and secondly I cant work out for the PHP how to cycle through all the newData to make sure that the result matches ALL the required variables rather than just 1 at a time.  Do I need to add any acceptable hotelid's into an array then compare these arrays at the end? Figure there must be a more elegant solution.
JavaScript Code:
 
var form = document.getElementById("amenOptions");
var amenData = "";
for (var i=0; i < form.elements.length; i++)
{
	var elem = form.elements[i];
	if (elem.type == "checkbox")
	{
		if(elem.checked == true)
		{
			amenData += elem.id + "_";
		}
	}
}
 
 
PHP Code:
 
$city = $_POST['city']; 
$amenData = $_POST['amendata'];
$newData = explode('_', $amenData);
for ($i=0; $i < count($newData); $i++)
{
	$result = mysql_query('SELECT * FROM hotelamen INNER JOIN hotels ON hotelamen.hotelid = hotels.hotelid WHERE hotels.cityid="' . $city . '" AND amenid="' . $newData[$i] . '"');
 
	$countResults = @mysql_numrows($result);
	for($i=0; $i<$countResults; $i++)
	{
		echo '<option id="'.mysql_result($result,$i,"hotelid").'">';
		echo mysql_result($result,$i,"hotelname").'</option>';
	}
}

Open in new window

Avatar of Vanq69

ASKER

aconrad have only just seen your solution but it seems you are using a similar method to myself - perhaps you could take a look at mine and see if you can spot any errors.  Thanks
Where do you have put the javascript code in the resulting page? If a statement referencing a form or element (form.elements in this case) is sitting outside a function body or event handler and is located before the HTML form it is referencing in a document's flow, the browser will return a script error when the page loads. Because statements outside a function body or event handler are executed as soon as the browser encounters them, the engine will not find the referenced form or element because it has not been loaded and built yet. This goes for any other element object in a document.
Avatar of Vanq69

ASKER

I have a separate Javascript file which is loaded in the header - this works fine for getting all the other form elements from the document just not this one.
But this piece of javascript in invoked on a particular event? A buttonclick, onload etc?
Are you sure that the error is on form.elements?
Avatar of Vanq69

ASKER

Its invoked by a button click.

Yes, If i remove form.elements and replace it with a static value then it passes through no problem.

If i execute the code then it wont run anything after form.elements line.

Fascinating. Well would be good if you can post the resulting browse source (the form in particular), maybe the html is not wellformed. What browser are you using?
Avatar of Vanq69

ASKER

I use firefox.



The PHP code is above, Here is the HTML code:


<form id="amenOptions">
	<?php
		include("amenOptions.php");
	?>
</form>

Open in new window

Avatar of Vanq69

ASKER

Actually just realised I had an open form element which was much lower down, have changed this and it now passes through.

The issue is how to run a query with a variable.  I want to basically be able to do a SELECT and only get the records which match 1. the cityid and 2. the checked amenities - which are contained in the value passed through.

I have split these into an array but cant work out how to structure the query.


$city = $_POST['city']; 
	$amenData = $_POST['amendata'];
	$newData = explode('_', $amenData);
	for ($i=0; $i < count($newData); $i++)
	{
		$result = mysql_query('SELECT * FROM hotelamen INNER JOIN hotels ON hotelamen.hotelid = hotels.hotelid WHERE hotels.cityid="' . $city . '" AND amenid="' . $newData[$i] . '"');
	
		$countResults = @mysql_numrows($result);
		for($i=0; $i<$countResults; $i++)
		{
			echo '<option id="'.mysql_result($result,$i,"hotelid").'">';
			echo mysql_result($result,$i,"hotelname").'</option>';
		}
	}

Open in new window

i'm interested in browser source (right mouse View Page Source) rather tan your php source.
Bytheway in yuor code there is a thing that semme an error:

echo '<input type="checkbox" id="'.mysql_result($result,$i,"amenid").'" value=""'.mysql_result($result,$i,"amenname").'">';

After the 'value' keyword there are two doublequotes and a single quote. I think that should be just a doublequote and a singlequote. This may result in an unterminated tag.
Avatar of Vanq69

ASKER

Have fixed that error - thank you.

The issue is now with the query - would the browser code still be useful?
ASKER CERTIFIED SOLUTION
Avatar of bugada
bugada
Flag of Italy image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
sorry should be

AND amenid IN (' . $amenData . ')'

instead of

AND amenid IN (' . $newData . ')'
Avatar of Vanq69

ASKER

elem.id is numerical.

how do you do the join after?
Avatar of Vanq69

ASKER

Dont worry if your not an expert in this area, if this doesnt work i'll award you the points for this bit and ask a specific question in the DB section.
I suppose that you pass your collected values to the ajax call as a parameter, in other words your amenData string.
Since I've changed it to an Array just do a amenData.join(",") to revert it as a comma separated string in you ajax call.
Avatar of Vanq69

ASKER

I dont think I have this bit right - it will only run without a semi colon after the join command.
for (var i=0; i < form.elements.length; i++)
	{
		var elem = form.elements[i];
		if (elem.type == "checkbox")
		{
			if(elem.checked == true)
			{
				amenData.push(elem.id);
                amenData.join(",")
			}
		}
	}

Open in new window

No you don't have to place that code here.

It's not easy to explain without the code.

In your php you do $_POST['amendata']; but somewere in your javascript code you pass the amendata as parameter to the ajax call. Probably as in the following code
function hotelSearch()
{
  if (xmlHttp)
  {
    params = "";
        
        var drop = document.getElementById('citiesDrop');
        var city = drop.options[drop.selectedIndex].value;
        
        // other values....
        
        if (city)
        {
                //amenData array must be global or defined in this function 
                params = "city=" + city + "&amenData=" + amenData.join(","); // + other values....
 
                
                if (params) cache.push(params);
                try
                {
                  // only continue if the connection is clear and cache is not empty
                  if ((xmlHttp.readyState == 4 || xmlHttp.readyState == 0) && cache.length>0)
                  {
                        // get next set of values from cache
                        var cacheEntry = cache.shift();
        
                        xmlHttp.open("POST", "hotelSearch.php", true);
                        xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
                        xmlHttp.setRequestHeader("Content-length", params.length);
                        xmlHttp.setRequestHeader("Connection", "close");
                        xmlHttp.onreadystatechange = executeHotelSearchChange;
                        xmlHttp.send(cacheEntry);
                  }
                  else
                  {
                        setTimeout("hotelSearch();", 1000);  
                  }
                }
                
                catch (e)
                {
                  displayError(e.toString());
                }
        }
                
        else
        {
                alert("Please select a City');
        }
  }
}

Open in new window

Avatar of Vanq69

ASKER

I am doing that but it wont run.  Here is the full code for the AJAX and PHP side - but I think the problem is javascript side as it wont execute.
Javascript
 
var drop = document.getElementById('citiesDrop');
	var city = drop.options[drop.selectedIndex].value;
	
	var form = document.getElementById("amenOptions");
	var amenData = "";
	for (var i=0; i < form.elements.length; i++)
	{
		var elem = form.elements[i];
		if (elem.type == "checkbox")
		{
			if(elem.checked == true)
			{
				amenData.push(elem.id);
			}
		}
	}
	
	if (city)
   	{
		params = "city=" + city + "&amenData=" + amenData.join(",");
		
		if (params) cache.push(params);
		try
		{
		  // only continue if the connection is clear and cache is not empty
		  if ((xmlHttp.readyState == 4 || xmlHttp.readyState == 0) && cache.length>0)
		  {
			// get next set of values from cache
			var cacheEntry = cache.shift();
	
			xmlHttp.open("POST", "hotelSearch.php", true);
			xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
			xmlHttp.setRequestHeader("Content-length", params.length);
			xmlHttp.setRequestHeader("Connection", "close");
			xmlHttp.onreadystatechange = executeHotelSearchChange;
			xmlHttp.send(cacheEntry);
		  }
 
PHP:
 
	$city = $_POST['city']; 
	$amenData = $_POST['amendata'];
	$result = mysql_query('SELECT * FROM hotelamen INNER JOIN hotels ON hotelamen.hotelid = hotels.hotelid WHERE hotels.cityid="' . $city . '" AND amenid IN (' . $amenData . ')');
 
	$countResults = @mysql_numrows($result);
	if($countResults > 0)
	{
		echo 1;
	}
	else if ($countResults == 0)
	{
		echo 2;
	}

Open in new window

change line 7 as follows
var amenData = new Array();

Open in new window

Avatar of Vanq69

ASKER

That passes through, but the query isnt reflecting the amenities selections only the city choice.  Any idea's? or should I ask in the DB forum?
Make a loop in javascript to construct the url and in php you will get an array if the name of the var you use in the ajax request is   par[]   (you need to escape it).

Also, you dont need selectedIndex to pass the select box var to ajax.

Make sure the variables get to javascript ok.
Here is a full example that gets the vars into the ajax's php just ok:



<?
if (isset($_GET['ajax'])) {
  print_r($_POST);
  die();
}
 
 
?>
 
<form name="frm">
 
<select name="city">
<option value="city one">one</option>
<option value="city two" selected>two</option>
<option value="city three">three</option>
</select>
 
<br>
 
Checkbox1 :<input type="checkbox" name="ele[]" value="a" checked> <Br>
Checkbox2 :<input type="checkbox" name="ele[]" value="b" checked><Br>
Checkbox3 :<input type="checkbox" name="ele[]" value="c" checked><Br>
Checkbox4 :<input type="checkbox" name="ele[]" value="d"><Br>
Checkbox5 :<input type="checkbox" name="ele[]" value="e" checked><Br>
 
 
</select>
</form>
 
 
<a href="#" onclick="req();return false;">Test it </a>
 
 
 
<script>
 
 
 
 
 
 
function req(seconds) {
   
	var urlvar = 'city='+ escape(document.forms['frm'].elements['city'].value) + '&';
	
    for ( var i in document.forms['frm'].elements['ele[]'] )
	{
	     if (document.forms['frm'].elements['ele[]'][i].checked)
	    {
	         urlvar += escape('var[]')+'='+escape(document.forms['frm'].elements['ele[]'][i].value) + '&';
	    }
	}
	//alert(urlvar);
 
	ajax_request('qwe.php?ajax=1','POST',urlvar,'checkresponse');
}
 
function checkresponse()
{
 
	var iserr = false;
	if (xmlhttp.readyState==4)
	{
		if (xmlhttp.status==200)
		{
			var resp = xmlhttp.responseText;
			alert(resp);
 
		}
		else
		{
			alert("Problem retrieving data:" + xmlhttp.statusText)
		}
	}
}
 
 
 
 
/**
* XML HTTP Request. Works with in cinjuction with the specified myfunc function which checks if the request was succesfull
*
* @param string $url
* @param POST-or-GET $method
* @param urlencoded-string $data
* @param string $myfunc
*/
function ajax_request(url,method,data,myfunc)
{
 
	if (window.XMLHttpRequest)
	{
		xmlhttp=new XMLHttpRequest()
		if (method=="GET")
		{
			xmlhttp.onreadystatechange=eval(myfunc)
			xmlhttp.open("GET",url,true)
			xmlhttp.send(null)
		}
		if (method=="POST")
		{
			xmlhttp.onreadystatechange=eval(myfunc)
			xmlhttp.open("POST", url, true);
			xmlhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
			xmlhttp.send(data)
		}
	}
	// code for IE
	else if (window.ActiveXObject)
	{
		xmlhttp=new ActiveXObject("Microsoft.XMLHTTP")
		if (xmlhttp)
		{
			if (method=="GET")
			{
				xmlhttp.onreadystatechange=eval(myfunc)
				xmlhttp.open("GET",url,true)
				xmlhttp.send()
			}
			if (method=="POST")
			{
				xmlhttp.onreadystatechange=eval(myfunc)
				xmlhttp.open("POST", url, true);
				xmlhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
				xmlhttp.send(data)
			}
		}
	}
}
 
 
</script>

Open in new window

Try to figure out what sql statement is executed, post it here so I can see if the params data are correct.
Avatar of Vanq69

ASKER

Im going to ask in the DB forum, thanks for your help.