The title says it all. In this tutorial I'll explain how to build a dynamic data grid for browsing data. This is not a perfect data grid solution that can be just dropped onto a page, it requires a bit of hands on tweaking, but the end result is pretty amazing.
This code uses AjaxAgent and PHP5's PDO DataBase Functions. I really like using PDO but if you're using something else you can very easily modify the code.
Source Code & Demo
Part 1: Setting Up AjaxAgent
Start by creating a new page and include the AjaxAgent library and initialize the server agent like this:
CODE:
-
include_once('agent.php');
-
$agent->init();
Now create a JavaScript block that will invoke the server function like this:
CODE:
-
<script type="text/javascript">
-
window.onload=function(){
-
returnPageData(1,'ProjName','DESC');
-
}
-
function returnPageData(offset,orderby,dir,perpage) {
-
//invoke the showDataGrid server fiunction
-
agent.call('ajaxFunctions.php','showDataGrid','returnPageData_Callback',offset,orderby,dir,perpage);
-
}
-
//call back Javascript function
-
function returnPageData_Callback(str) {
-
//get the element and bind the datagrid to it
-
document.getElementById("ajaxgrid1").innerHTML = str;
-
}
-
-
</script>
By placing returnPageData(1,'ProjName','DESC') in the window.load function we are invoking the data grid for the first time with some default parameters.
returnPageData(The Row Number to Start At,The Column to Order the Data By,The Direction of the Order: ASC or DESC)
Once we are inside the function returnPageData we then invoke the agent.call by passing it the page with the PHP code ajaxFunctions.php, the PHP function showDataGrid, the callback returnPageData_Callback and lastly some parameters offset,orderby,dir,perpage. The perpage parameter is optional
When the returnPageData_Callback function is invoked we pass the ajax response to and html element that will display the grid.
Last on the page is the element that grid will be bound to:
CODE:
-
<div id='ajaxgrid1'></div>
Be sure to place all of this code in it's own .php page and then create a new page called ajaxDataGrid.php.
Part 2: Building the Data Grid
This is where things get a little harder so stay sharp. The ajaxDataGrid.php contains 5 functions that make up the datagrid.
- showDataGrid - returns the DataGrid and Navigation
- getProjects - returns an array of Project Data
- pc_indexed_links - manages the Grid Navigation
- pc_print_link - prints the Grid Navigation Links
- phpDataGrid - creates and returns the DataGrid
The only function called by us is showDataGrid which we will pass some parametes the JavaScript function returnPageData. All of the other functions are called by showDataGrid so we do not need to worry about them just yet.
Part 2.1: showDataGrid
This is the main function that does all of the work for us:
View the showDataGrid() code
PHP:
-
function showDataGrid($setoffset,$setorderby,$setdir){
-
//create an array of columns
-
//columnName is the SQL column name
-
//columnDisplay is the friendly column display name
-
$columns[0] =
array("columnID"=>
"0",
"columnName"=>
"ProjName",
"columnDisplay"=>
"Name");
-
$columns[1] =
array("columnID"=>
"1",
"columnName"=>
"ProjDesc",
"columnDisplay"=>
"Description");
-
-
//set some defaults
-
$offset = 0;
-
$per_page = 5;
-
$column = $columns[0];
-
$orderby = $column['columnName'];
-
$dir = 'ASC';
-
-
if ($setoffset> 0) {
-
$offset = $setoffset;
-
}
-
if ($setorderby != '') {
-
$orderby = $setorderby;
-
}
-
if ($setdir != '') {
-
$dir = $setdir;
-
}
-
//get some data
-
$projects = getProjects($offset,$per_page,$orderby,$dir);
-
//display the data navigation
-
$html .= pc_indexed_links
(count(getProjects
()),
$offset,
$per_page,
$orderby,
$dir);
-
//display the datagrid
-
$html .= phpDataGrid($projects,$columns,$offset,$per_page);
-
//echo the results
-
-
}
Part 2.2: getProjects & SQL
For this tutorial I am using my Projects DataBase from the gotfoo labs:
Here is a cut-down version of the Projects Table with some default data.
View the Projects SQL code
SQL:
-
CREATE TABLE `tblProjects` (
-
`ProjID` int(11) NOT NULL AUTO_INCREMENT,
-
`ProjName` varchar(100) NOT NULL DEFAULT '',
-
`ProjDesc` text,
-
`DateUpdated` datetime DEFAULT NULL,
-
PRIMARY KEY (`ProjID`)
-
) TYPE=InnoDB AUTO_INCREMENT=13;
-
-
INSERT INTO `tblProjects` VALUES (1, 'Project One',Project One Description', '2006-11-10 10:04:36');
-
INSERT INTO `tblProjects` VALUES (2, 'Project Two',Project Two Description', '2006-11-10 10:04:36');
-
INSERT INTO `tblProjects` VALUES (3, 'Project Three',Project Three Description', '2006-11-10 10:04:36');
-
INSERT INTO `tblProjects` VALUES (4, 'Project Four',Project Four Description', '2006-11-10 10:04:36');
-
INSERT INTO `tblProjects` VALUES (5, 'Project Five',Project Five Description', '2006-11-10 10:04:36');
-
INSERT INTO `tblProjects` VALUES (6, 'Project Six',Project Six Description', '2006-11-10 10:04:36');
-
INSERT INTO `tblProjects` VALUES (7, 'Project Seven',Project Seven Description', '2006-11-10 10:04:36');
-
INSERT INTO `tblProjects` VALUES (8, 'Project Eight',Project Eight Description', '2006-11-10 10:04:36');
-
INSERT INTO `tblProjects` VALUES (9, 'Project Nine',Project Nine Description', '2006-11-10 10:04:36');
-
INSERT INTO `tblProjects` VALUES (10, 'Project Ten',Project Ten Description', '2006-11-10 10:04:36');
-
INSERT INTO `tblProjects` VALUES (11, 'Project Eleven',Project Eleven Description', '2006-11-10 10:04:36');
-
INSERT INTO `tblProjects` VALUES (12, 'Project Twelve',Project Twelve Description', '2006-11-10 10:04:36');
-
INSERT INTO `tblProjects` VALUES (13, 'Project Thriteen',Project Thriteen Description', '2006-11-10 10:04:36');
And here is the PHP code that gets the Project Data:
View the getProjects() code
PHP:
-
function getProjects($offset='',$per_page='',$orderby='',$dir='') {
-
//get a connection
-
$mysql = new PDO('mysql:host=[HOST];dbname=[DATABASE]','[USERNAME]','[PASSWORD]');
-
-
//set the ORDER BY clause with a direction
-
if($orderby != ''){
-
$strSQLExtra .=" ORDER BY ".$orderby." ".$dir;
-
}
-
//set the LIMIT and OFFSET
-
if($offset> 0) {
-
$strSQLExtra .= " LIMIT ".$per_page." OFFSET ".($offset-1);
-
}else if($per_page> 0){
-
$strSQLExtra .= " LIMIT ".$per_page;
-
}else{
-
$strSQLExtra = '';
-
}
-
-
//the SQL
-
$strSQL = "SELECT * FROM tblProjects ".$strSQLExtra;
-
//echo $strSQL;
-
-
-
-
//execute the sql and bind it to an array
-
foreach( $mysql->query( $strSQL ) as $row ){
-
$projects[$row['ProjID']] = $row;
-
}
-
-
$mysql = null;
-
-
//return the data
-
return $projects;
-
}
The most important parameters are the $per_page which sets the LIMIT and the $offset sets the position to start gathering data at.
Part 2.3: Data Grid Navigation
I'll admit right up front that I found the data navigation code in the PHP Cookbook 2ed but I modified the code to allow for the $orderby, $dir and $per_page parameters.
View the Navigation code
PHP:
-
function pc_indexed_links($total,$offset,$per_page,$orderby,$dir) {
-
$separator = ' | ';
-
$html = '';
-
-
//extra parameters
-
$urlParams =
array("orderby"=>
$orderby,
"dir"=>
$dir,
"perpage"=>
$per_page);
-
-
// print "<<Prev" link
-
$html .= pc_print_link($offset == 1, '<<Prev', $offset - $per_page,$urlParams);
-
-
// print all groupings except last one
-
for ($start = 1, $end = $per_page;
-
$end <$total;
-
$start += $per_page, $end += $per_page) {
-
$html .= $separator;
-
$html .= pc_print_link($offset == $start, "$start-$end", $start,$urlParams);
-
}
-
-
$end = ($total> $start) ? "-$total" : '';
-
-
$html .= $separator;
-
$html .=pc_print_link($offset == $start, "$start$end", $start,$urlParams);
-
-
// print "Next>>" link
-
$html .= $separator;
-
$html .=pc_print_link($offset == $start, 'Next>>',$offset + $per_page,$urlParams);
-
-
return $html;
-
}
-
-
function pc_print_link($inactive,$text,$offset='',$urlParams=null){
-
$html = '';
-
if($inactive) {
-
$html .= "<span class='inactive'>".$text."</span>\n";
-
} else {
-
$html .= "<span class='active'>\n";
-
$html .= "<a href='#' OnClick=returnPageData(".$offset.",'".$urlParams['orderby']."','".$urlParams['dir']."',".$urlParams['perpage'].");return false'>$text</a></span>\n";
-
}
-
return $html;
-
}
Part 2.4: The Data Grid
This is the heart and soul of the whole matter.
For the PHP function phpDataGrid we will pass in 4 parameters: and array of data, an array of columns, the page offset and the number of records per page.
In the first for loop we are looping over the $columns array to create the columns & headers as well as links to sort the column.
Once we are past that we have a foreach loop which a) loops over the $dataobjects array and then loops over the columns. In the column loop we are using the $column['columnName'] a.k.a the SQL column name to get a value of the $dataobjects array.
View the phpDataGrid() code
PHP:
-
function phpDataGrid($dataobjects,$columns,$offset,$per_page){
-
-
if($dataobjects == null){
-
return "No Data";
-
}
-
$html .= "<table border='0' width='90%'>";
-
$html .= "<tr bgcolor = '#EFEFEF'>";
-
-
//loop over the $columns array to create the columns & headers as well as links to sort the column
-
for($i=0;$i<count($columns);$i++){
-
-
$column = $columns[$i];
-
$html .= "<td width='30%'><strong>";
-
$html .= $column['columnDisplay'];
-
$html .= " <a href='#' OnClick=returnPageData(".$offset.",'".$column['columnName']."','ASC',".$per_page.");return false'>+</a>";
-
$html .=" / ";
-
$html .= "<a href='#' OnClick=returnPageData(".$offset.",'".$column['columnName']."','DESC',".$per_page.");return false'>-</a> ";
-
$html .= "</strong></td>";
-
-
}
-
$html .= "</tr>";
-
$count = 0;
-
foreach($dataobjects as $object){
-
if($count % 2) {
-
$bgcolor = '#EFEFEF';
-
} else {
-
$bgcolor = '#ffffff';
-
}
-
$html .= "<tr valign=top bgcolor=".$bgcolor.">";
-
for($i=0;$i<count($columns);$i++){
-
$column = $columns[$i];
-
$html .= "<td>";
-
-
$html .= "</td>";
-
-
}
-
$html .= "</tr>";
-
$count++;
-
}
-
-
$html .= "</table>";
-
return $html;
-
}
Once all of the rows have been processed we're done and we return the DataGrid back to the calling function, showDataGrid.
Part 2.5: Very Important Quirk/Hack
I went crazy this week because I had AgaxAgent working on one site but not another. I spent hours trying to get the DataGrid to work. Then I found the answer.
At the very bottom of ajaxDataGrid.php we need to include the AjaxAgent library and initialize it again. I don't know but if it's not there you'll get nothing but errors.
CODE:
-
include_once("agent.php");
-
$agent->init();
We're done!!
Demo