8.3 HTML_Table
PEAR模块HTML_Table允许你通过PHP代码创建、修改表格。基本过程是配置所需的单元格数和行数,然后使用这个PHP类来输出该表格。使用该模块,随时可以获得一个清晰、易于维护的表格。
为了展示将HTML_Table的功能和可维护性与Ajax功能相结合能够实现什么,在此创建了一个与数字计算器相关的功能。虽然和Excel并不完全一样,但这个例子用来展示如何创建和使用HTML_Table模块而言是足够了,同时还将展示如何更有效、更人性化、更简单地执行Ajax功能。这个例子如图8-5和图8-6所示。

图8-5 简单地输入值,就像在电子表格应用程序中那样

图8-6 该HTML_Table应用程序将自动对这些值进行累加
如图8-5及图8-6所示的HTML_Table应用程序提供了一组字段,可以用来计算每一列的总和。现在我们看看它是如何实现的。首先看看sample8_2.php文件中的代码。它创建了一个HTML_Table对象实例作为整个应用程序的基础框架。程序代码如下:
<!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
// 设置表格的大小
$maxrows = 3;
$maxcols = 4;
// 创建该表格并设置其属性
require_once ("HTML/Table.php");
$table = new HTML_Table(array('cellpadding' => 0,
'cellspacing' => 0,
'border' => 1,
'class' => 'tablehead'));
$table->setCaption ("HTML_Table use with Ajax");
//创建穿行的数据集。
$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);
}
}
//创建一个标题为“totals(合计)”的分隔行。
$totdata = array ("Totals");
$table->addRow($totdata, array('colspan' => $maxcols,
'align' => 'center',
'bgcolor' => '#c0c0c0',
'color' => '#fff'));
//然后创建合计单元格。
$totcounter = 0;
for ($j = 0; $j < $maxcols; $j++){
$attrs = array('id' => 'tot' . $totcounter,
'height' => '20',
'width' => intval(100 / $maxcols) . '%',
'bgcolor' => '#eee',
'align' => 'center');
$table->setCellAttributes($maxcols, $j, $attrs);
$totcounter++;
}
echo $table->toHTML();
?>
</body>
</html>
在此使用PEAR中的PHP模块对表格中每个单元格的属性进行了配置,以创建一个Ajax应用程序。这虽然看起来很妙,但并非所有的都需要这么复杂。这段代码首先初始化一个新的HTML_Table对象。然后在此基础上提供所需的标题,并逐步创建所需的行。
在这个脚本中有两个重要的部分。首先是创建第一组空单元格时,注意在第一次调用setCellAttributes函数时,将onclick的值设置成调用createtext函数。这样就能够将每个单元格配置为被单击时调用createtext函数。该脚本中另一个重要的部分是合计单元格的创建,在此要注意id的值被赋予了特定的数字值。这对于从基于Ajax的脚本中载入计算出的合计值是十分重要的。
这段代码最后一步是调用toHTML方法,它将把这段PHP代码转成HTML表格。到此,基础框架就完成了。接下来我们将分析functions.js文件中的代码,看看这些基于Ajax的函数是如何实现的。
首先要分析的函数是createtext。该函数的参数包括创建文本框的位置,在表格中的列以及文本框的唯一编号。当用户单击表格中的某个单元格时,将调用该函数。如果文本框还没有创建,则动态地在该单元中创建一个文本框。在此使用CSS来改变文本框的外观(没有边框、宽度和高度与单元格相同),使用户不知道在此创建了文本框。
在文本框创建后,将焦点赋予它,使用户能够在其中输入某些值。而在用户完成值的输入并离开文本框时,将调用loadtotals函数:
//functions.js
function createtext (where, col, counter, numCols, numRows)
{
var id = 'box' + counter;
if (where.innerHTML == '' || where.innerHTML == ' ') {
var theEvent = 'loadTotals(' + col + ', ' + numCols + ', ' + numRows + ')';
where.innerHTML = '<input id="' + id + '" type="text" class="noshow"'
+ ' onblur="' + theEvent + '" />';
}
document.getElementById(id).focus();
}
loadtotals函数本身并不复杂,但其包含了许多数据验证的工作。因为用户可以输入任何类型的数据,而在此只希望是整型(integer),对该问题的处理必须很认真。会使该脚本执行失败的另一个麻烦是在所有相关的文本框创建之前执行加法运算。所以,在此有许多验证工作需要做。
要计算各列的合计值,首先需要对每一列进行遍历,对每一列中的各个行进行累加。在累加所有值时必须先进行检查,确保所有累加的值都是整型的。使用isNaN函数可以确认传入的是否为非整型值,如果是非整型则将其值转为0。还有一个操作是必需的,要计算的数据首先都是表示为String型的,因此要将其先转成数字型的数据类型,例如整型。该任务可以在JavaScript中用parseInt函数实现,如下列代码所示。然后就只需累加这些整型值,把结果输出到合计单元格的innerHTML属性中,从而完成计算操作。
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;
}







