Forum Moderators: coopster

Message Too Old, No Replies

PHP and Javascript

How did I get them talking to each other?

         

grandpa

11:07 pm on Oct 12, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Getting Javascript and PHP to communicate.

I am by no means an expert at either of these languages, and there are times when I want them to work together. Those times often include extended sessions of pouting, cussing and hair pulling. I'm offering a solution to a specific problem I encountered, in the hope that someone else can make some use from it. Here's the situation:

I have a page that gives my visitors several hundred options, all at once. They pick the options by specifying a quantity for any option. When they're all done they click just once to send everything to the cart.

I also have a special offer on some of these items, Buy X Get Y Free. So I have to keep track of some total values.Until now, I had no way of capturing the total quantity on the page (not the number of options selected). In other words, it's just as easy to order 2 of everything, or 3, or any combination. But that total quantity was elusive.

I came up with a solution that combines the use of Javascript and PHP. Bear in mind that I believe this solution can be written more efficiently. I just don't know to do that yet.

To begin, I am displaying a form that is populated from a data table on my server (MySQL). One key factor at this point was to consider that the number of items displayed in this form may vary, as we move in new items or remove others. The form contains an input text box for every item where I accept a value, the quantity wanted.

Each input field in this form also has a corresponding hidden input field that I use to send data to my cart. The hidden field names are dynamically assigned a value from my script, so that each is unique. Here's an example of my form fields:

<input type="text" size="2" name="VARqty$varcount" value="0">
<input type="hidden" name="AddItem$varcount" value="$fcod $frag¦$whsprc¦VARqty$varcount¦$wkpack¦$wkwgt¦">

These are written inside a while loop in my script as the table is processed. The value of $varcount gives me the dynamic name values that I use in the form. There is another hidden input field in this form, which will get its value back from the Javascript counter. Here's how it looks.

<input type="hidden" name="icount" size="2" value="0">

The form submit contains an onClick statement to call the Javascript function.

<input type="submit" onClick=\"iCount(this.form)">

I also display the input fields in a table, so PHP is used to help dynamically construct the table elements. Here's a look at the entire form. (NOTE: some the the PHP variables you see were made available thru a previous SELECT statement. What's relevant here are the variables $varcount and $count.)

$count = 0;
$varcount = 1;
$query = "SELECT * FROM my_table WHERE status = 'A' ORDER BY desc";
$result = mysql_query($query) or die("Sorry, I didn't find a damn thing : " . mysql_error());
echo "<form action=\"http://www.example.net/cgi-bin/cart.cgi\" method=\"POST\" name=\"Add1\">";
echo "<input type=\"hidden\" name=\"AddItem\" value=\"VARpack\">";
echo "<br><table border=\"1\" width=\"100%\" style=\"text-align: left;\"><tr><td width=\"33%\">";
while ($line = mysql_fetch_array($result, MYSQL_ASSOC)) {
$frag = $line['desc'];
$fcod = $line['code'];
$count++;
$wkItemId = $fcod . " " . $wkpack;
if ($count < 3) {
echo "<input type=\"text\" size=\"2\" name=\"VARqty$varcount\" value=\"0\">
<input type=\"hidden\" name=\"AddItem$varcount\" value=\"$fcod¦$whsprc¦VARqty$varcount¦$wkpack¦$wkwgt¦\"><b> $frag </b>";
echo "</td>";
echo "<td>";
$varcount++;
}
if ($count >= 3 ) {
echo "<input type=\"text\" size=\"2\" name=\"VARqty$varcount\" value=\"0\">
<input type=\"hidden\" name=\"AddItem$varcount\" value=\"$fcod¦$whsprc¦VARqty$varcount¦$wkpack¦$wkwgt¦\"><b> $frag </b>";
echo "</td></tr>";
echo "<tr><td>";
$varcount++;
$count = 0;
}
} // end while
echo "<input type=\"hidden\" name=\"icount\" size=\"2\" value=\"0\">";
echo "</td></tr>";
echo "</table>";
echo "<table class=maintab>";
echo "<tr><td>&nbsp;</td></tr>";
echo "<tr class=addcart><td>";
echo "<input class=\"CheckOut\" name=\"I1\" src=\"http://www.mydomain.com/images/add.gif\" type=\"image\" alt=\"Click to Add all your widgets to the shopping cart\" onClick=\"iCount(this.form)\">";
echo "</td></tr>";
echo "<tr><td>Click the Cart button to add all your<br>$SAVADD, $addpack widgets with one click.</td></tr>";
echo "</table>";
echo "</form>";
echo "</td>";
echo "</tr>";
echo "</table>";

So now, how to get a total of all the VARqty$varcount input fields? Did I hear someone say Javascript?

First, on a page this size (116K and growing), I think the Javascript solution adds a lot of extra overhead. Dial-up users will be able to brew a pot of coffee waiting for this page. Personally, I think the wait will have been worth it.

I had to consider that since the number of input fields may vary, so too will the number of elements I'll require with a Javascript solution. OK, so that's what arrays are for, and that's certainly an option for an upgraded version of this page. But for now, I went with brute force and paid the price in overhead.

First, I use PHP again, to give me the number of rows in my table.

$query = "SELECT * FROM my_table WHERE status = 'A' ";
$result = mysql_query($query);
$num_rows = mysql_num_rows($result);

Next, and most critical to getting this counter to work at all, is to echo the Javascript with PHP. Or least a part of it. I went ahead and coded it all that way. The PHP for-loop executes when the page is loaded, building the Javascript variables that will be needed.

When the function is called from the form, the value of VARqty$varcount in the form is given to max$i. Note here how the value of the variable $i was used to create unique variables on the fly, and they correspond to the values created in the form.

Next, I multiply the value of max$i by 1 - it's still a text value until that happens - then assign the numeric value to num$i. I think I can probably safely use max$i to hold the numeric value, but rather than research that item I did what I knew would work. Then I get the sum total of the form in my Javascript variable, total. The last item for this function is return total to my form, in icount.

Here's a look at the complete Javascript function:

echo "<head>";
echo "<SCRIPT LANGUAGE=\"JavaScript\">";
echo "function iCount(form) {";
echo "var total = 0;";
for ($i = 1; $i <= $num_rows; $i++) {
echo "var max$i = form.VARqty$i.value;";
echo "var num$i = max$i * 1";
echo "total = total + num$i;";
}
echo "document.Add1.icount.value = total;";
echo "}";
echo "</script>";
echo "</head>";

So far I've populated a form, filled in the text boxes with numbers, and submitted my choices off to the cart. The Javascript function got called and returned the total quantity on this page to a field in my form. I still can't get to the total quantity. There's more to do.

After POST'ing the form, the PHP script uses this statement to retrieve the total.

$icount = $_POST["icount"];

Now the variable $icount can be used (within its current scope) in the script.

One final thing remains. I am using the value in $icount to update a table (next version will write cookies), and discovered in testing that every time I clicked the browser refresh button, any existing value in $icount would be re-stated to the database. I was increasing my count without adding any new items to the cart!

Then the final step of this process then is to unset the POST'ed variables with this:

unset($HTTP_POST_VARS);

It's not the most elegant piece of code, and I've already spotted a few modifications that should improve on the solution. But, if you're stuck trying to figure out how to make Javascript and PHP talk to each other, your solution could be buried in here.

As previously stated, this can all probably be coded to be a bit more efficient, and maybe to reduce to overhead. There is also room for improvement - validating numeric input on my form, for instance. I don't think that a text entry to my form will result in any security breach, but that possibility does exist and should be considered. And there may well be other items that I haven't even considered yet.

SofterLogic UK

11:46 am on Oct 13, 2004 (gmt 0)

10+ Year Member



A useful tutorial - thanks. One point however you may have overlooked - the clean solution that cookies can give for communication.

coopster

1:46 pm on Oct 13, 2004 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



SofterLogic UK, you seemed to have overlooked the point that grandpa did not overlook ;)


One final thing remains. I am using the value in $icount to update a table (next version will write cookies)

I use javascript as a convenience to the user, too, grandpa. And yes, hidden fields and/or cookies are a great mechanism for doing so. One point I would like to add is that we always need to keep in mind that the user can alter values before they are returned to the server. You may want to count your totals again on the server side if you aren't already.

Congratulations on your success!

mincklerstraat

6:44 pm on Oct 13, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Very nice tutorial grandpa over a tough, sticky issue. You've really risen to the challenge, produced code that works, and then taken on the extra challenge of explaining to the world how you did all of it (for me, often the most time-consuming). Thanks for this nice tutorial - have been looking over it and your code, hope to post more later.