Experiment: Datatable class
Output a HTML data table in PHP easily
In my recent meanderings though object-oriented land, I wanted something to help me get my head round this pretty important method of programming. If I call myself a developer I really should know what most developers in the world do, shouldn’t I? What I needed as something to get my teeth into, an example from my own experience I could turn into OOP code.
And what better than something for my projectGenie system. In particular I wanted to simplify the bloated code I used to output HTML tables of data, and turning it into a class seemed to be the best way to do it.
About OOP
So, firstly an introduction about object-orientated programming, and bear with me because I’m still learning here. This style of development sees most things as ‘objects’ A car is an object, so is a house, so is a record in a database. Pretty much all objects have properties. A property is something that we can use to describe part of the object: the car is read, the house has 4 bedroom, the database row has a field called ‘ID’ with the value ‘123′. An objects properties could b described as variables outside of the object.
Objects also have methods. A method is something we can do with the object. We can start the car, unlock the house, or change the database row. A method in an object would be called a function outside of that object. There may be some technical differences, but functions and methods are pretty much the same thing.
A simple example
To be honest none of that, although I read it many times in many different places, made much sense to me until I actually looked at a simple objects’ code and could translate that into what I wanted. So I’ll do the same with you, just look at this. This is in PHP, but any OOP language will work the same way even if the syntax is different.
<?php
class car {
// the properties
$this->color = "red";
$this->engineSize = 1.8;
$this->doors = 5;
$this->engineStarted = false;
// a couple of methods
function start(){
$this->engineStarted = true;
}
function paint($color){
$this->color = $color;
}
}
?>
Now you may be thinking ‘Hurrah, but so what?’ and I don’t blame you. After all, that’s nothing you can’t do with just a few varibles and functions. But what have we done? We’ve created a class, which is a template for an object. It’s a class called ‘car’ and has a few properties and methods. But how do we use this; at the moment it’s just sitting there waiting for someone to come and rev the engine up. We have to create the car like this:
<?php $myCar = new car(); // set some of the properties $myCar->color = "green"; $myCar->engineSize = 1.1; ?>
So now $mycar is an instance of the object ‘car’, and it’s green and has a measly 1.1 engine. Let’s paint it black, shall we?
<?php
// get out the paint
$myCar->paint("black");
?>
And now we have a little KITT car. Lovely.
Now it’s your turn
Imagine you want to create an object. What object would it be? Something that exists already, or something completely new? What properties would it have (how could you describe it) ? And what methods would it have (what could you do with it) ? Here’s something I just thought of:
<?php
class alienLifeForm {
// the properties
$this->numberOfLegs = 19;
$this->stapleDiet = "Wierd alien plantlife, and human flesh on Sundays";
$this->penchantFor = array("Country and Western music","Knitting","Watersports");
// a couple of methods
function sayHello(){
$this->tentacles = "waving";
}
function eatHuman($color){
$this->tentacles = "chomping";
}
}
?>
See how easy that is? Fantastic, eh?
The datatable class
So now we’re all OK with the general idea of objects, classes, properties and methods, let me introduce you to a friend of mine; the DataTable object. This nifty object, all neatly wrapped up in a class for your delictation, allows the canny PHP developer to easily output HTML tables containing data. Not only that, but you can style the fields, add styles and IDs to rows, and generally have a whale of a time.
The full code is below, and you can dissect that if you want. For now I’m just going to show you a simple example that demonstrates the capabilities of the object. Follow the comments in the code, and click here for the example.
<?php
// Create the new datatable
$t = new DataTable();
// Set the field names using the property 'fields'
// these are in a array of strings
$t->fields = array("ID","Title","Description");
// Set the format of the fields using the property 'fieldFormat'
// each field format is a string
// Use '%%[field id]' to display the corresponding field value,
// 1 for the first field, 2 for the next field etc
// Example 1: this displays field 1 in strong tags
$t->fieldFormat(1, "<strong>%%1</strong>");
// Example 2: this displays field 2 with a hyperlink to field 1
$t->fieldFormat(2, "<a href=\"%%1\">%%2</a>");
// Example 3: this displays a phrase in emphasis tags with fields 3
// and 1 in the text
$t->fieldFormat(3, "<em>%%3 with ID %%1</em>");
// Add rows to the table using the 'addRow' method
// each row is an array
$t->addRow(array("1", "Link 1", "This is link 1"));
$t->addRow(array("2", "Link 2", "This is link 2"));
$t->addRow(array("3", "Link 3", "This is link 3"));
$t->addRow(array("4", "Link 4", "This is link 4"));
$t->addRow(array("5", "Link 5", "This is link 5"));
// This row will span the width of the table, as there are less fields
// than there should be. The datatable object will automatically
// pad missing columns to the end of the row
// This row will have an ID of 'insertedrow' and a class of 'glow'
$t->addRow(array("Inserted row"), array("class"=>"glow","id"=>"t$id"));
// Add some more rows
$t->addRow(array("6", "Link 6", "This is link 6"));
$t->addRow(array("7", "Link 7", "This is link 7"));
$t->addRow(array("8", "Link 8", "This is link 8"));
$t->addRow(array("9", "Link 9", "This is link 9"));
$t->addRow(array("10", "Link 10", "This is link 10"));
// Finally, show the data table
$t->showDataTable();
?>
So the only thing remaining is to give you the script to download. And here it is in it’s completeness, ready for copying and pasting. The usual GPL licence applies.
<?php
// ======================================
// THE PHP DATATABLE CLASS
// Author: Chris Taylor, stillbreathing.co.uk
// This work is protected under the GPL Licence
// Full details at http://www.opensource.org/licenses/gpl-license.php
// ======================================
class DataTable
{
// initial variables
function __construct() {
// set some variables
$this->summary = "Table summary";
$this->caption = "Table caption";
$this->altClasses = array("","alt");
$this->fields = array("No fields set");
$this->rows = array();
$this->rowParams = array();
$this->headerRepeat = 0;
$this->fieldFormats = array();
}
// bind a MySQL mysql_fetch_array array to the datatable
function dataBind($arr){
// set the fields to nothing
$this->fields = array();
// loop the field names and add them
foreach($arr as $key => $value){
$this->addField($key);
}
// set the rows to nothing
$this->rows = array();
// loop each row and add it
for ($r=0; $r<count($arr); $r++){
$this->addRow($arr[$r]);
}
}
// add a field
function addField($fieldName){
// add the values to a new row
$this->fields[] = $fieldName;
}
// add a row
function addRow($values,$params=array()){
// add the values to a new row
$this->rows[count($this->rows)] = $values;
// if there are row parameters set
if (count($params)>0){
// add any parameters
$this->rowParams[count($this->rows)-1] = $params;
}
}
// format a field
function formatField($fieldNo, $rowNo){
$value = "";
// if the field has a format
if ($this->fieldFormats[$fieldNo+1]){
$output = $this->fieldFormats[$fieldNo+1];
// modify the field value with the format
for ($y=0; $y<count($this->rows[$rowNo]); $y++){
$fieldId = $y+1;
$value .= "[$y] ";
$output = preg_replace("/%%$fieldId/", $this->rows[$rowNo][$y], $output);
$value .= $output ."<br />";
}
} else {
$output = $this->rows[$rowNo][$fieldNo];
}
// return the new value
return $output;
}
// set up the field format
function fieldFormat($fieldNo, $format){
// add the field format to the fieldFormats array
$this->fieldFormats[$fieldNo] = $format;
}
// show the header row
function showHeader(){
$header = "";
// print the header row
$header .= " <tr>\n";
// loop the fields
foreach ($this->fields as $field) {
// print each field
$header .= " <th>".$field."</th>\n";
}
// end the header row
$header .= " </tr>\n";
return $header;
}
// show the data table
function showDataTable(){
$output = "";
// print the table
$output .= "<table summary=\"".$this->summary."\">\n";
// print the caption
$output .= "<caption>".$this->caption."</caption>\n";
$output .= $this->showHeader();
// initialise variables
$altCounter = 0;
$altClass = "";
$h = 1;
// loop each row
for ($x=0; $x<count($this->rows); $x++) {
// if it is time to show the header
if ($h==$this->headerRepeat){
// show the header
$output .= $this->showHeader();
$h = 1;
}
$row = $this->rows[$x];
// alternate the row classes
if ($this->altClasses){
if ($this->altClasses[$altCounter]!=""){ $altClass = " class=\"".$this->altClasses[$altCounter]."\""; } else { $altClass=""; }
if ($altCounter==count($this->altClasses)-1){ $altCounter=0; } else { $altCounter++; }
}
// set the parameters to nothing
$params = "";
// if there are parameters for this row set
if (count($this->rowParams[$x])>0){
// loop the parameters
while (list($attribute, $parameter) = each($this->rowParams[$x])) {
// if the parameter is 'class'
if (strtolower($attribute)=="class"){
// replace the altClass variable
$altClass = " ".strtolower($attribute)."=\"$parameter\"";
} else{
// otherwise build the parameters
$params .= " ".strtolower($attribute)."=\"$parameter\"";
}
}
}
// print the row
$output .= " <tr$altClass$params>\n";
// set the colSpan to 0
$colSpan = 0;
$colSpanAttribute = "";
// if this row has less columns than the number of fields
if (count($row)<count($this->fields)){
$colSpan = (count($this->fields)-count($row))+1;
}
// loop each cell
for ($i=0; $i<count($row); $i++) {
$value = $row[$i];
$value = $this->formatField($i, $x);
// make the colspan attribute
if ($colSpan>0 && $i==(count($row)-1)){ $colSpanAttribute = " colspan=\"$colSpan\""; }
// print the cell
$output .= " <td$colSpanAttribute>".$value."</td>\n";
}
// end the row
$output .= " </tr>\n";
// increment the header repeat variable
$h++;
}
// end the table
$output .= "</table>\n\n";
print $output;
}
}
?>
Future developments: I’m working on a ‘dataBind’ method (you can see it in the script above, actually) that will allow the almost-instant binding of a MySQL recordset to a table, saving you the hassle of doing all that pesky looping malarkey. Hopefully it will be done soon.
This is the online home of Chris Taylor, web developer and designer from Yorkshire, U.K.. Please take a look around using the menu below, 



