The HTML_TablePEAR module is a code set designed to allow you to create and modify tables using PHP code. Basically, you set up the cells and rows you want, and then use the PHP class to output the table. By using this module, you will get a clean, easily main- tained table every time.
In order to show off what’s possible when you combine the efficiency and maintain- ability of HTML_Tablewith Ajax functionality, I’ve created something of a number
calculator. While it’s not exactly Microsoft Excel, this example does an adequate job of showing how to create and use the HTML_Tablemodule, and then use it to perform Ajax- based functionality that is efficient, ergonomic, and easy for the user to make use of. This example is shown in Figures 8-5 and 8-6.
Figure 8-5.Simply enter your values like you would in a spreadsheet application.
Figure 8-6.Our HTML_Table application automatically adds up the values.
The HTML_Tableapplication, as shown in Figures 8-5 and 8-6, works by creating a set of fields that the user can make use of to calculate a sum of the rows. You have seen what it looks like—now let’s have a look at how it works. The first aspect of the code that you need to look at is the sample8_2.phpfile. It creates an instance of an HTML_Tableobject that you will use as the framework for your application. Consider the following block of code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Sample 8_2</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <link rel="stylesheet" type="text/css" href="style.css" />
<script type="text/javascript" src="xmlhttp.js"></script> <script type="text/javascript" src="functions.js"></script> </head>
<body> <?php
// Set the size of the table $maxrows = 3;
$maxcols = 4;
// Create the table and set its properties require_once ("HTML/Table.php");
'cellspacing' => 0, 'border' => 1,
'class' => 'tablehead')); $table->setCaption ("HTML_Table use with AJAX");
//Create our data set of empty rows. $counter = 0;
for ($i = 0; $i < $maxrows; $i++){ for ($j = 0; $j < $maxcols; $j++){ $counter++; $event = sprintf('createtext(this, %d, %d, %d, %d)', $j, $counter, $maxcols, $maxrows);
$attrs = array('onclick' => $event,
'width' => intval(100 / $maxcols) . '%', 'height' => 20,
'align' => 'center'); $table->setCellAttributes($i, $j, $attrs); }
}
//Create a "totals" separator. $totdata = array ("Totals");
$table->addRow($totdata, array('colspan' => $maxcols, 'align' => 'center', 'bgcolor' => '#c0c0c0', 'color' => '#fff')); //Then create the totals boxes.
$totcounter = 0;
for ($j = 0; $j < $maxcols; $j++){
$attrs = array('id' => 'tot' . $totcounter, 'height' => '20',
'width' => intval(100 / $maxcols) . '%', 'bgcolor' => '#eee',
$table->setCellAttributes($maxcols, $j, $attrs); $totcounter++; } echo $table->toHTML(); ?> </body> </html>
As you can see, by making use of the ability to set attributes within each individual cell of the table, you can create an Ajax application using a PHP module from PEAR. While that certainly seems like a mouthful, it is not necessarily all that complicated. The code starts by initializing a new HTML_Tableobject. You then build upon it from there by supplying it a caption and gradually building the rows you want.
There are two crucial portions of this script, however. The first to note is when you are creating your first set of empty cells. Notice that, within the first call to the setCell➥
Attributesfunction, you assign the onclickvalue to call the createtextfunction. What this will do is assign a value to each cell that tells it to call the createtextfunction when- ever the cell is clicked. The next crucial element of this script happens when you create the Totals boxes. You will notice that the idvalue is assigned to a specific number. This will be crucial when loading in the calculated totals from your Ajax-based scripts.
The last piece of functionality that occurs is the call to the toHTMLmethod, which converts this block of PHP code into an HTML table. At this point, your framework has been set. Let’s look at your functions.jsfile to see how the Ajax-based functionality is achieved.
The first function you want to have a look at is the createtextfunction. This function takes in as arguments the location to create the text box, the column this box is part of, and the unique number of the box itself. Basically, when a user clicks on a cell in your table, this function is called. If the box has not yet been created, you will dynamically create the box within the cell. You use CSS to mask the box (no border, same width and height) so that the user does not know that a box has been created.
Once the box has been created, you assign focus to it and allow the user to enter some values. When the user finishes entering the values and clicks off of the box, the
loadtotalsfunction is called:
//functions.js
function createtext (where, col, counter, numCols, numRows) {
var id = 'box' + counter;
if (where.innerHTML == '' || where.innerHTML == ' ') {
where.innerHTML = '<input id="' + id + '" type="text" class="noshow"' + ' onblur="' + theEvent + '" />';
}
document.getElementById(id).focus(); }
The loadtotalsfunction is not so much complicated as it is a validation nightmare. Because the user could potentially enter any form of data, and you only want integerval- ues (in this case), you must be very careful how you attempt this. Another hurdle to the execution of this script can arise if the function tries to perform the addition before all of the relevant boxes are created. As you can see, there is a bit of validation to do.
In order to calculate the total of the column, you first run a loop through each col- umn by going through the number of rows in a column. Now, before you can add up all of the values, a check must be done to ensure that the three values to be added are of an Integer type. You can use the isNaNfunction to determine if a non-Integer has slipped through the cracks, and if so, default said value to zero again. It is also imperative, when calculating data that will be at first interpreted as a String data type, to change the String data type into a numerical data type, such as Integer. This can be done in JavaScript using the parseIntfunction, as shown in the following code example. At this point, you simply need to add up your Integer values and submit the sum to the column total cell’s
innerHTMLproperty, thereby finishing the calculation.
function loadTotals(col, numCols, numRows) {
var total = 0; var cellId = 0;
for (var row = 0; row < numRows; row++) { cellId = row * numCols + col + 1; var id = "box" + cellId;
var elt = document.getElementById(id); if (elt) { val = parseInt(elt.value); if (!isNaN(val)) total += val; } }
document.getElementById('tot' + col).innerHTML = total; }
Summary
This chapter has shown how to sidestep some crippling issues that Ajax can introduce, and has brought to light the true benefit of Ajax. By setting up Ajax functionality properly, you can save your users a lot of grief and do what was intended by this technology in the first place: provide a solid, seamless, powerful web site–browsing experience. By combin- ing a solid Ajax framework with simple, clean, easily maintainable server-side PHP, you have yourself a recipe for a successful end product.
Now that you’ve gone through the ins and outs of Ajax and displaying it properly to the web page, it’s time to move on to a slightly more advanced topic: web services. Now, I know this was the big buzz word not too long ago (right before Ajax, seemingly), but that doesn’t mean that the technology is now old and stale. Quite the opposite in fact, seeing as you can combine the two to create something truly special. Stay tuned, as Chapter 9 moves into some very cool Ajax- and PHP-based functionality.