Solved

Passing Variable Number of Variables through AJAX

Posted on 2009-05-06
27
667 Views
Last Modified: 2013-12-12
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

0
Comment
Question by:Vanq69
  • 14
  • 11
  • 2
27 Comments
 
LVL 10

Expert Comment

by:bugada
Comment Utility
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

0
 

Author Comment

by:Vanq69
Comment Utility
Thanks, how do I then add them to the params string as well as retrieve them in the php file using $_POST
0
 
LVL 4

Expert Comment

by:aconrad
Comment Utility
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

0
 

Author Comment

by:Vanq69
Comment Utility
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

0
 

Author Comment

by:Vanq69
Comment Utility
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
0
 
LVL 10

Expert Comment

by:bugada
Comment Utility
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.
0
 

Author Comment

by:Vanq69
Comment Utility
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.
0
 
LVL 10

Expert Comment

by:bugada
Comment Utility
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?
0
 

Author Comment

by:Vanq69
Comment Utility
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.

0
 
LVL 10

Expert Comment

by:bugada
Comment Utility
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?
0
 

Author Comment

by:Vanq69
Comment Utility
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

0
 

Author Comment

by:Vanq69
Comment Utility
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

0
 
LVL 10

Expert Comment

by:bugada
Comment Utility
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.
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 

Author Comment

by:Vanq69
Comment Utility
Have fixed that error - thank you.

The issue is now with the query - would the browser code still be useful?
0
 
LVL 10

Accepted Solution

by:
bugada earned 500 total points
Comment Utility
I'm not a db guru, and i don't know your db schema, but probably this ca give you an hint:

pass the amenData post in this form: "id1","id2","id3"

the use the IN caluse without exploding the array.



var form = document.getElementById("amenOptions");

var amenData = new Array();

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 + '"'); // remove quotes if id is supposed to be  numerical

                        // then do a amenData.join(",") to convert it to a string to pass as parameter to the ajax call

                }

        }

}
 
 

$city = $_POST['city']; 

        $amenData = $_POST['amendata'];

        /* $newData = explode(',', $amenData); */
 

                $result = mysql_query('SELECT * FROM hotelamen INNER JOIN hotels ON hotelamen.hotelid = hotels.hotelid WHERE hotels.cityid="' . $city . '" AND amenid IN (' . $newData . ')');

        

                $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

0
 
LVL 10

Expert Comment

by:bugada
Comment Utility
sorry should be

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

instead of

AND amenid IN (' . $newData . ')'
0
 

Author Comment

by:Vanq69
Comment Utility
elem.id is numerical.

how do you do the join after?
0
 

Author Comment

by:Vanq69
Comment Utility
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.
0
 
LVL 10

Expert Comment

by:bugada
Comment Utility
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.
0
 

Author Comment

by:Vanq69
Comment Utility
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

0
 
LVL 10

Expert Comment

by:bugada
Comment Utility
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

0
 

Author Comment

by:Vanq69
Comment Utility
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

0
 
LVL 10

Expert Comment

by:bugada
Comment Utility
change line 7 as follows
var amenData = new Array();

Open in new window

0
 

Author Comment

by:Vanq69
Comment Utility
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?
0
 
LVL 4

Expert Comment

by:aconrad
Comment Utility
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

0
 
LVL 10

Expert Comment

by:bugada
Comment Utility
Try to figure out what sql statement is executed, post it here so I can see if the params data are correct.
0
 

Author Comment

by:Vanq69
Comment Utility
Im going to ask in the DB forum, thanks for your help.
0

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

International Data Corporation (IDC) prognosticates that before the current the year gets over disbursing on IT framework products to be sent in cloud environs will be $37.1B.
Since pre-biblical times, humans have sought ways to keep secrets, and share the secrets selectively.  This article explores the ways PHP can be used to hide and encrypt information.
The viewer will learn how to dynamically set the form action using jQuery.
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now