I have a class I created that I have been using for years to do almost exactly what you are looking to do. Although you don't really need to use PHP5 syntax to do it. I've attached the class file and an example file that shows how it works. The example is a calendar and it generates it's own example data array, but any array will work. Just put the files in a web accessible directory and call the listMaker.example.php file. This is just an example, so there are a number of things I am not doing, like sanitizing the form input data.

There are 3 essential settings to it:
1. The template for the data. In your case, it's what is in your while loop without the "tr"
2. The data, which is a multi-dimensional associative array. It's the array you get when you retrieve data from mysql the way you are.
3. The row delimiter. In your case "</tr><tr>"

When you call the makeList function, you tell it how many columns you want. It then creates however many rows are necessary based on the size of the data array. So if your data array has 9 items and you specify 3 columns, it will create 3 rows.

I did not mention pagination, because you should only be retrieving enough records from the database to build the page, not all the data. You would do this by adding a "LIMIT" clause to your query. There was a pagination discussion not too long ago, you should search the archives for that discussion.

Hope that helps.

Brent
<?php

class ListMaker {
	protected $template		= null;
	protected $templates	= array('default'=>'');
	protected $defaultData	= array();
	protected $cellData		= array();
	protected $rowData		= array();
	protected $conditionalVals	= array();
	protected $conditionalData	= array('checked'=>' CHECKED');
	protected $altRowData	= array();
	protected $altRowTag	= null;
	protected $rowPrefix	= '<tr>';
	protected $rowSuffix	= '</tr>';
	protected $tagPrefix	= '%%';
	protected $tagSuffix	= '%%';
	
	public function __construct() {
		
	}
	
	public function reset() {
		$this->template		= null;
		$this->templates	= array('default'=>'');
		$this->defaultData	= array();
		$this->cellData		= array();
		$this->rowData		= array();
		$this->conditionalVals	= array();
		$this->conditionalData	= array('checked'=>' CHECKED');
		$this->altRowData	= array();
		$this->altRowTag	= null;
		$this->rowPrefix	= '<tr>';
		$this->rowSuffix	= '</tr>';
		$this->tagPrefix	= '%%';
		$this->tagSuffix	= '%%';
	}
	
	/**
	 * Set the prefix and suffix for search tags
	 *
	 * @param string $prefix
	 * @param string $suffix
	 */
	public function setTagDelims($prefix, $suffix) {
		$this->tagPrefix	= $prefix;
		$this->tagSuffix	= $suffix;
	}
	
	/**
	 * Set row delimiters. Typically this would be simple <tr></tr>,
	 * but it could be anything. You can include substitutions tags
	 * in the delimiters which will be replaced with data items
	 * set with setAlternatingRowData()
	 *
	 * @param string $prefix
	 * @param string $suffix
	 */
	public function setRowDelims( $prefix, $suffix ) {
		$this->rowPrefix	= $prefix;
		$this->rowSuffix	= $suffix;
	}
	
	/**
	 * Set default data substitution tags
	 *
	 * @param array $data	associative array, keys are the substitution tags to be replace with the values
	 * @param boolean $append	whether to append to or overwrite the default data
	 * @return int
	 */
	public function setDefaultData( $data, $append=0 ) {
		if ( !is_array($data) ) {
			return -1;
		}
		if ($append) {
			$this->defaultData	= array_merge($this->defaultData, $data);
		} else {
			$this->defaultData	= $data;
		}
		return 1;
	}
		
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $searchTag
	 * @param unknown_type $replaceList
	 * @return unknown
	 */
	public function setAlternatingRowData( $searchTag, $replaceList ) {
		if ( !is_array($replaceList) ) {
			return -1;
		}
		$this->altRowTag			= $searchTag;
		$this->altRowData			= $replaceList;
	}
	
	/**
	 * Load a preset cell template
	 *
	 * @param string $name	name of template to set
	 * @return int
	 */
	public function setCellTemplate( $tplName ) {
		echo 'This should not be called.';
	}
	
	/**
	 * If there is a form field (i.e. checkbox) set which values to precheck
	 * Can be used as a conditional substitution based on a certain value in the dataset
	 *
	 * @param array $conditionalVals	values to check for conditional substitution
	 * @param mixed $conditionalData	values to use substitution
	 * @return unknown
	 */
	public function setConditional( $conditionalVals=null, $conditionalData=null ) {
		if ( is_null($conditionalVals) ) {
			$this->conditionalVals	= array();
		} else if ( !is_array($conditionalVals) ) {
			$this->conditionalVals	= explode(',', str_replace(' ',$conditionalVals) );
		} else {
			$this->conditionalVals	= $conditionalVals;
		}
		if ( is_array($conditionalData) ) {
			$this->conditionalData	= $conditionalData;
		}
		return 1;
	}
	
	/**
	 * Load a custom cell template
	 *
	 * @param string $tpl
	 */
	public function loadTemplate( $tpl ) {
		$this->template	= $tpl;
	}
	
	/**
	 * Create the list based using the current settings
	 *
	 * @param int $cols		number of columns before creating a new row. Use 0 to create a single row
	 * @param array $data	associative array, keys are the substitution tags to be replace with the values
	 * @param string $keyField	data field in $data to use for comparing conditional values
	 * @return string
	 */
	public function makeList( $cols, $data, $keyField=null ) {
		if ( !is_array($data) ) {
			return -1;
		}
		$dataCnt	= count( $data );
		$dataList	= '';
		$i			= 0;
		$rowCntr	= 0;
		$rowDataCnt	= count($this->altRowData);
		$dataKeys			= array_keys($data);
		$searchFields		= array_keys( array_merge( $this->defaultData, $data[key($data)] ) );
		$searchVals			= explode( '+|+', $this->tagPrefix . implode( $this->tagSuffix.'+|+'.$this->tagPrefix, $searchFields ) . $this->tagSuffix );
		$searchValsConditional	= explode( '+|+', $this->tagPrefix . implode( $this->tagSuffix.'+|+'.$this->tagPrefix, array_keys($this->conditionalData) ) . $this->tagSuffix );
		while ( $i<$dataCnt ) {
			// Start a new row
			if ( !is_null($this->altRowTag) ) {
				$dataList	.= str_replace($this->altRowTag, $this->altRowData[round($rowCntr%$rowDataCnt)], $this->rowPrefix);
			} else {
				$dataList	.= $this->rowPrefix;
			}
			$colCntr	= 0;
			while( $colCntr<$cols && $i<$dataCnt ) {
				$replaceVals		= array_merge($this->defaultData, $data[$dataKeys[$i]]);
				if ( !is_null($keyField) && in_array($data[$i][$keyField], $this->conditionalVals) ) {
					$tmpTemplate	= str_replace($searchValsConditional, $this->conditionalData, $this->template);
					$dataList		.= str_replace($searchVals, $replaceVals, $tmpTemplate);
				} else {
					$dataList		.= str_replace($searchVals, $replaceVals, $this->template);
				}
				$colCntr++;
				$i++;
			}
			$rowCntr++;
			$dataList	.= $this->rowSuffix;
		}
		// Strip out any tags not substituted with data
		return preg_replace('/'.$this->tagPrefix.'.*?'.$this->tagSuffix.'/', '', $dataList);
	}
	
}
<?php

include('../classes/listMaker.class.php');
$cListMaker	= new ListMaker();

$numOfColumns	= 7;
//Check if form field override is set
if( isset($_POST['numOfColumns']) ) {
	$numOfColumns	= $_POST['numOfColumns'];
}

$pageOutput	= <<<OUTPUT
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd";>
<html xmlns="http://www.w3.org/1999/xhtml"; xml:lang="en" lang="en">
<head>
<title>ListMaker Example</title>

<style type="text/css">
.date, .predate {
	font-weight: bold;
}
.predate {
	color: #999;
}
.hilite {
	background-color: #cc6;
}
</style>
<body>
This is an example of how to use the ListMaker class for creating lists.<br />
The concept is to specify an "item" template, row delimiter and substitution data.<br />
You can specify the numbers of columns to generate, any number of alternating row colors, and conditional substitution
<p>
Select some days and submit the form. The days will then be hilighted in the specified color and the checkboxes will remain checked.
<p>
<form name="example" action="" method="POST">
Numebr of Columns: <input type="text" name="numOfColumns" value="$numOfColumns" size="2" maxlength="2">
<input type="submit" name="submit" value="Submit Busy Days"><br />
<table border="1" cellpadding="2" cellspacing="0">
<p>
OUTPUT;

//Example of how to use the ListMaker class

// THE FOLLOWING GENERATES SOME DATA
// The resulting array is an array containing
// various name/value pairs for parts of a day (date, name, day of the year, etc)

//Create some sample data
$showMonth	= ( isset($_GET['m']) ? $_GET['m'] : date('n') );

// Using current month, create a calendar
$crntInfo['year']		= date('Y');
$crntInfo['month']		= $showMonth;
$crntInfo['date']		= date('j');
$crntInfo['days']		= date('t', strtotime($crntInfo['year'].'-'.$showMonth.'-1') );

// Generate information for each day
// Pad array up until first day of the month
$prevMonthDays			= date('t', strtotime($crntInfo['year'].'-'.($crntInfo['month']-1).'-1') );
$padCount				= date('w', strtotime($crntInfo['year'].'-'.$crntInfo['month'].'-1') );
$startDate				= $prevMonthDays-$padCount+1;

for( $x=0; $x<$padCount; $x++ ) {
	// Get day parts (mday, wday, mon, year, yday, weekday, month)
	$monthDays[$x]				= getdate( strtotime($crntInfo['year'].'-'.($crntInfo['month']-1).'-'.($startDate+$x)) );
	// Add a field to hold event text
	$monthDays[$x]['event']		= '';
	// Add a field to styling the date
	$monthDays[$x]['dateStyle']	= 'predate';
}
$x--;

for($y=1; $y<=$crntInfo['days']; $y++ ) {
	// Get day parts (mday, wday, mon, year, yday, weekday, month)
	$monthDays[$x+$y]			= getdate( strtotime($crntInfo['year'].'-'.$crntInfo['month'].'-'.$y) );
	// Add a field to hold event text
	$monthDays[$x+$y]['event']	= '';
	// Add a field to styling the date
	$monthDays[$x+$y]['dateStyle']	= 'date';
}




// ***** THE REAL SAMPLE CODE *******

// Create data template, change it to however you want it to look
// Items enclosed in %% will be substituted with data from the associative array
// Add any "fields" present in the associative array (i.e. year, month, wday, mday, weekday, ...)
$cellTpl	= <<<TPL
<td width="120" height="60" valign="top" class="%%tdhilite%%">
<div class="%%dateStyle%%" style="float: right">%%mday%%</div>
%%weekday%%<p />
<input type="checkbox" name="%%busyfield%%" value="%%yday%%" %%busychecked%%>%%yday%%
</td>
TPL;
$cListMaker->loadTemplate($cellTpl);

// Set the default data to be used for every item (i.e. field name, css)
$cListMaker->setDefaultData( array('busyfield'=>'busy[]', 'tdbgcolor'=>'') );
// Set which values should be used for conditional substitution
// Also set the background of the cell to a different color
$cListMaker->setConditional( $_POST['busy'], array('busychecked'=>'CHECKED', 'tdhilite'=>'hilite') );

// Create delimiter template
$cListMaker->setRowDelims('<tr style="background-color: %%rowColor%%;">', '</tr>');

// Create alternating row colors, as many as you like in the array
$cListMaker->setAlternatingRowData('%%rowColor%%', array('#f0f0f0', '#f6f6f6') );

// Create the list, specifying number of column, the data array and the key field
$theList	= $cListMaker->makeList($numOfColumns, $monthDays, 'yday');
$pageOutput	.= $theList;

$pageOutput	.= <<<BODY
</table>
</form>
BODY;

echo $pageOutput;
echo 'Data Array used to created Grid:<br />';
echo nl2br(print_r($monthDays,true));


On Dec 11, 2007, at 12:16 PM, anang tawiah wrote:


I am a relative php amateur who is trying to kind of master the php 5 syntax and I have using Larry Ulmanns php and mysql 2nd edition book.  The problem I am facing is that in the authors example he lists all the results.

 

What I want to do for this project is to display the following product information in rows and columns whereby;

 

  • i could  specify the number of columns and rows per page (using php 5 syntax)
  • And finally I also want to paginate the result set (using php 5 syntax)

 

I know this might sound trivial to most of you ‘Gurus’ on this list (which is why I finally decided to stop trying to figure it out myself and ask for help) and I appreciate your help in advance.

 

 

 

<?php # Script 14.6 - browse_prints.php

// This page displays the available prints (products).

 

// Set the page title and include the HTML header.

$page_title = 'Browse the Prints';

include ('./includes/header.html');

 

require_once ('../mysql_connect.php'); // Connect to the database.

 

// Are we looking at a particular artist?

if (isset($_GET['aid'])) {

            $aid = (int) $_GET['aid'];

            if ($aid > 0) {

                        $query = "SELECT artists.artist_id, CONCAT_WS(' ', first_name, middle_name, last_name) AS name, print_name, price, description, print_id FROM artists, prints WHERE artists.artist_id = prints.artist_id AND prints.artist_id =$aid ORDER BY prints.print_name";

            } else {

                        $query = "SELECT artists.artist_id, CONCAT_WS(' ', first_name, middle_name, last_name) AS name, print_name, price, description, print_id FROM artists, prints WHERE artists.artist_id = prints.artist_id ORDER BY artists.last_name ASC, prints.print_name ASC";

            }

} else {

            $query = "SELECT artists.artist_id, CONCAT_WS(' ', first_name, middle_name, last_name) AS name, print_name, price, description, print_id FROM artists, prints WHERE artists.artist_id = prints.artist_id ORDER BY artists.last_name ASC, prints.print_name ASC";

}

 

// Create the table head.

echo '<table border="0" width="90%" cellspacing="3" cellpadding="3" align="center">

<tr>

<td align="left" width="20%"><b>Artist</b></td>

<td align="left" width="20%"><b>Print Name</b></td>

<td align="left" width="40%"><b>Description</b></td>

<td align="right" width="20%"><b>Price</b></td>

</tr>';

 

// Display all the prints, linked to URLs.

$result = mysqli_query ($dbc, $query);

while ($row = mysqli_fetch_array ($result, MYSQL_ASSOC)) {

 

            // Display each record.

            echo "   <tr>

                        <td align=\"left\"><a href="">

                        <td align=\"left\"><a href="">

                        <td align=\"left\">{$row['description']}</td>

                        <td align=\"right\">\${$row['price']}</td>

            </tr>\n";

           

} // End of while loop.

 

echo '</table>'; // Close the table.

 

mysqli_close($dbc); // Close the database connection.

include ('./includes/footer.html');

 

?>

 

 

 

Thanks,



_______________________________________________
New York PHP Community Talk Mailing List

NYPHPCon 2006 Presentations Online

Show Your Participation in New York PHP

_______________________________________________
New York PHP Community Talk Mailing List
http://lists.nyphp.org/mailman/listinfo/talk

NYPHPCon 2006 Presentations Online
http://www.nyphpcon.com

Show Your Participation in New York PHP
http://www.nyphp.org/show_participation.php

Reply via email to