Need help with simple paging class

aii guys…really stuck up here…my attempt paginating my recordset no to avail…so far…I manage to get display the numbering for the total record as u can see here…

somerecord
somerecord
somerecord
somerecord
somerecord
somerecord
somerecord
somerecord
somerecord
somerecord
somerecord
somerecord
somerecord
somerecord
somerecord
somerecord
somerecord
somerecord
somerecord
somerecord

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94

my desire just wanna display previous and next and next 10 record till reach total records

as u can see here…

somerecord
somerecord
somerecord
somerecord
somerecord
somerecord
somerecord
somerecord
somerecord
somerecord
somerecord
somerecord
somerecord
somerecord
somerecord
somerecord
somerecord
somerecord
somerecord
somerecord

previous 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 next

after user click next it will display another 20 records

previous 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 next and so forth…

Hope someone will shed me some light…here’s the mockup illustration waht I after…
testpaging.php



include("DataBase.class.php");
include("Pagination.class.php");

	$db = DataBase::getInstance();
	$row = $db->executeGrab("SELECT * FROM ".PADU_NOTICE." WHERE DEPARTMENT_CODE='04'");	
	if($row){		
		$numRows = $db->getNumRow();
		if(isset($_GET['p'])){
		 	$pg = $_GET['p'];
		}else{
			 $pg = 1;
		}
		$targetPage = $_SERVER['PHP_SELF'];	
		
		
		$pager = Pagination::getInstance($row, $pg, $targetPage, 20,$numRows);
		if(is_object($pager)){
			foreach($pager->__getPage($pg) as $item) {
    				echo 'NOTICE NO :: '.$item['NOTICE_NO'].'<br>';
			}
			echo "<br/>\
";
			echo "<br/>\
";
			echo "<br/>\
";
			echo "<div align='center'>".$pager->__getNav()."</div>";
		}
	}
	



here’s the paginationclass



class Pagination{
	

    static private $instance = false;
	
    public $_properties;
    public $pages;
	public $data = array();
	public $_pageNum;
	public $_targetPage;
	public $_perPage;
	public $_nav;
	private $_numrows;
	

    private function __construct($data, $pageNum, $targetPage, $perPage, $numRows){
		$this->_data = $data;
		$this->_pageNum = $pageNum;
		$this->_targetPage = $targetPage;
		$this->_perPage = $perPage;
		$this->_numrows = $numRows;
		$this->pages = array();
        $this->buildPaging($this->_data);
       	$this->buildNav();
    }


    public static function getInstance($data=NULL, $pageNum=NULL, $targetPage=NULL, $perPage=NULL, $numRows=NULL){
		if(!Pagination::$instance) {
            Pagination::$instance = new Pagination($data, $pageNum, $targetPage, $perPage, $numRows);
        }
        return Pagination::$instance;
    }
	
    public function __set($name, $value) {
        if(isset($name)) {
            $this->_properties[$name] = $value;
        }
    }

    public function __get($name){
        if(isset($this->_properties[$name])){
            return $this->_properties[$name];
        }else{
            return NULL;
        }
    }

    public function buildPaging($dataArr=NULL){
        if(is_array($dataArr)){
            $numberPages = count($dataArr)/$this->_perPage;
            if (round($numberPages)<$numberPages) {
                $numberPages = round($numberPages) + 1;
            }
            $k=0;
            for ($i=0;$i<$numberPages;$i++){
                for($j=0;$j<$this->_perPage;$j++){
                    if(isset($dataArr[$k])){
                        $this->pages[$i][$j] = $dataArr[$k];
                    }
                    $k++;
                }
            }
        }
    }

/////////////////////////////portions printing the numbering//////////////////////////////

//need help here..

    public function buildNav(){
		$this->_nav = '';
        foreach($this->pages as $key => $page){
			if($key == $this->_pageNum){ 
				$style = ' style="font-weight:bold;text-decoration:none;color:#000;"';
			} else {
				$style = '';
			}
			$this->_nav .= '<a href="' .$this->_targetPage. '?page=' .$key. '"' . $style . '>' .$key. '</a>&nbsp;';
       }
		
    }

///////////////////////////////////////////////////////////////
   
    public function __getNav() {
        return $this->_nav;
    }
   
    public function __getPage($num) {
        return $this->pages[$num-1];
    }
	
	public function __clone(){
		trigger_error("Clone is not allowed.", E_USER_ERROR);
	}
}



Hope someone will shed me some light…thanks you in advanced

Well now that the hard part is done… Nice work, oddz.

oddz’s demo is even more brilliant than you realize it sounds like. display() is a beautifully written function that outputs your paging in an unordered list element, <ul>. That’s an excellent choice semantically; browsers and other devices will understand that all of your paging is part of related set. The beauty is that you now have that structure to refer to throughout your site. Since you don’t like the native appearance of the list, you need to dive into your stylesheet and rewrite the appearance rules. I would target the pagination class, with your selector and style appropriately. list-style-type allows you to control the type of bullet (including none). You can get all the list items to position horizontally by resetting their display to inline.

Removing the bullets and displaying the list horizontally can be accomplished with some simple CSS. I modified the previous example with the basic template for accomplishing that particular display of the list.

In regards to showing the data that can be achieved any way you wish. The whole idea here is to completely separate the pagination from the display of list. Just to show you an example though I modified the action to store the result set of the pagination action. I than added a method to retrieve that data and list it via a loop. In reality though you can decide what way is best based on your code structure.

The purpose of this class is to provide a reusable interface to paginate data and front-end API. In regards to listing that data that is all up to you. You would list any way that you would normally display a list of data – that is the easy part.


<?php
class Pagination {
	
	protected
	
	/*
	* Configuration defaults
	*/
	$_arrConfig = array(
		'limit'=>10
		,'page'=>1
		,'basePath'=>'#'
		,'label'=>'Items'
		,'visiblePages'=>5
		,'pageFlag'=>'{page}'
	)
	
	/*
	* Data to be passed to template
	*/
	,$_arrTemplateData = array()
	
	/*
	* function to pass resolved offset and limit
	*/
	,$_onPaginate
	
	/*
	* extra arguments to pass to to pagination callback 
	* such as data source or db connection
	*/
	,$_arrArgs;
	
	public function __construct($onPaginate,$arrConfig=array(),$arrArgs=array()) {
	
		$this->_onPaginate = $onPaginate;
		$this->_arrArgs = $arrArgs;
	
		foreach($arrConfig as $strKey=>$mixValue) {
			if(array_key_exists($strKey,$this->_arrConfig)) {
				$this->_arrConfig[$strKey] = $mixValue;
			}
		}
	}
	
	public function paginate() {
	
		/*
		* Calculate page offset 
		*/
		$intOffset = ($this->_arrConfig['page']-1)*$this->_arrConfig['limit'];
		
		/*
		* Paginate and get number of found rows 
		*/
		$intFoundRows = call_user_func_array($this->_onPaginate,array_merge(array($intOffset,$this->_arrConfig['limit']),$this->_arrArgs));
		
		/*
		* Assign template data 
		*/
		$this->_arrTemplateData['limit'] = $this->_arrConfig['limit'];
		$this->_arrTemplateData['page'] = $this->_arrConfig['page'];
		$this->_arrTemplateData['offset'] = $intOffset;
		$this->_arrTemplateData['found_rows'] = $intFoundRows;
		$this->_arrTemplateData['total_pages'] = $intFoundRows < $this->_arrConfig['limit']?1:ceil($intFoundRows/$this->_arrConfig['limit']);
		$this->_arrTemplateData['visible_pages'] = $this->_arrConfig['visiblePages'];
		$this->_arrTemplateData['base_path'] = $this->_arrConfig['basePath'];
		$this->_arrTemplateData['label'] = $this->_arrConfig['label'];
		$this->_arrTemplateData['page_flag'] = $this->_arrConfig['pageFlag'];
		
		/*
		* Return the pagination template 
		*/
		return $this->display();
	}
	
	public function display() {
		extract($this->_arrTemplateData);
		
		if($total_pages <= $visible_pages) {
    		$page_start = 1;
    		$page_end = $total_pages;
		} else if($page <= ceil($visible_pages/2)) {
    		$page_start = 1;
    		$page_end = $visible_pages;
		} else if($page > ($total_pages - ceil($visible_pages/2))) {
    		$page_start = $total_pages - (ceil(($visible_pages/2)*2)-1);
    		$page_end = $total_pages;
		} else {
    		$page_start = $page-(floor($visible_pages/2));
    		$page_end = $page+(floor($visible_pages/2));
		}
		
		$return = sprintf(
   			'<div class="summary"><p class="pages">&#37;u %s</p><p class="total">%u %s</p></div>'
    		,$total_pages
    		,$total_pages == 1?'Page':'Pages'
    		,$found_rows
    		,$found_rows == 1?$label:$label
		);
		
		$return.= sprintf('<ul class="pagination">');
		$return.= sprintf(
    		'<li class="first">%s%s%s</li>'
    		,$page == 1?'':sprintf('<a href="%s">',str_replace($page_flag,1,$base_path))
    		,'First'
    		,$page == 1?'':'</a>'
		);    
		$return.= sprintf(
    		'<li class="previous">%s%s%s</li>'
   		 	,$page == 1?'':sprintf('<a href="%s">',str_replace($page_flag,($page-1),$base_path))
    		,'Previous'
    		,$page == 1?'':'</a>'
		);
		foreach(range($page_start,$page_end,1) as $i) {
    		$return.= sprintf(
        		'<li%s>%s%s%s</li>'
        		,$page == $i?' class="current"':''
        		,$page == $i?'':sprintf('<a href="%s">',str_replace($page_flag,$i,$base_path))
        		,$i
        		,$page == $i?'':'</a>'
    		);
		}
		$return.= sprintf(
			'<li class="next">%s%s%s</li>'
			,$page == $total_pages?'':sprintf('<a href="%s">',str_replace($page_flag,($page+1),$base_path))
    		,'Next'
    		,$page == $total_pages?'':'</a>'
		);
		$return.= sprintf(
    		'<li class="last">%s%s%s</li>'
    		,$page == $total_pages?'':sprintf('<a href="%s">',str_replace($page_flag,$total_pages,$base_path))
    		,'Last'
    		,$page == $total_pages?'':'</a>'
		);
		$return.= sprintf('</ul>');
		
		return $return;
		
	}

}

define('PADU_NOTICE','table_name');

class Action {

	private
	
	$_arrData = array();

	public function paginate($offset,$limit) {
	
		$strSQL = sprintf(
			"SELECT * FROM %s WHERE DEPARTMENT_CODE='04' LIMIT %s,%s"
			,PADU_NOTICE
			,mysql_real_escape_string($offset)
			,mysql_real_escape_string($limit)
		);
		
		$result = mysql_query($strSQL);
		
		while($row=mysql_fetch_assoc($result)) {
			$this->_arrData[] = $row;
		}
		
		return 400;
	
	}
	
	public function getData() {
		return $this->_arrData;
	}

}

$action = new Action();

$func = create_function('$offset,$limit,$action','return $action->paginate($offset,$limit);');
$pg = new Pagination($func,array(
	'basePath'=>$_SERVER['PHP_SELF'].'?p={replace_me_with_page}'
	,'pageFlag'=>'{replace_me_with_page}'
	,'label'=>'Departments'
	,'limit'=>5
	,'page'=>isset($_GET['p']) && is_numeric($_GET['p']) && $_GET['p'] != 0?$_GET['p']:1
	,'visiblePages'=>10
),array($action));
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
        "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
	<meta http-equiv="content-type" content="text/html; charset=utf-8">
	<title>Untitled</title>
	<style type="text/css">
	.pagination {
		text-align: center;
	}
	.pagination li {
		display: inline-block;
	}
	*+html .pagination li {
		display: inline;
	}
	* html .pagination li {
		display: inline;
	}
	</style>
</head>
<body>
	<?php echo $pg->paginate(); ?>
	<?php foreach($action->getData() as $data) { ?>
	<?php /* display list ... */ ?>
	<?php } ?>
</body>
</html>

Using CSS to format the list is the standard solution.

See for example: Perfect pagination style using CSS

Wow…oddz…thanks for the brilliant class that;s what I’ve been looking for…it awsome…I’ve been playing with ur class and this is the result

466 Pages

2330 TotalRecordDepartments04

First
Previous
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Next
Last

It works ok only how to make the numbering to Horizontal and remove the bullet in ur class…eg:-

First Previous bla…bla…bla// Next Last –> Horizontal instead of Vertical
one more things where I have to echo my value from database Ive been studying ur class but seems lost have no idea where shoul I echo my 1st 20 records value as my example above…so where should I echo [‘MY_DTBASE_VALUE’]…synchronize with the paging…

Thanks again mate…for the big help…


<?php
class Pagination {
	
	protected
	
	/*
	* Configuration defaults
	*/
	$_arrConfig = array(
		'limit'=>10
		,'page'=>1
		,'basePath'=>'#'
		,'label'=>'Items'
		,'visiblePages'=>5
		,'pageFlag'=>'{page}'
	)
	
	/*
	* Data to be passed to template
	*/
	,$_arrTemplateData = array()
	
	/*
	* function to pass resolved offset and limit
	*/
	,$_onPaginate
	
	/*
	* extra arguments to pass to to pagination callback 
	* such as data source or db connection
	*/
	,$_arrArgs;
	
	public function __construct($onPaginate,$arrConfig=array(),$arrArgs=array()) {
	
		$this->_onPaginate = $onPaginate;
		$this->_arrArgs = $arrArgs;
	
		foreach($arrConfig as $strKey=>$mixValue) {
			if(array_key_exists($strKey,$this->_arrConfig)) {
				$this->_arrConfig[$strKey] = $mixValue;
			}
		}
	}
	
	public function paginate() {
	
		/*
		* Calculate page offset 
		*/
		$intOffset = ($this->_arrConfig['page']-1)*$this->_arrConfig['limit'];
		
		/*
		* Paginate and get number of found rows 
		*/
		$intFoundRows = call_user_func_array($this->_onPaginate,array_merge(array($intOffset,$this->_arrConfig['limit']),$this->_arrArgs));
		
		/*
		* Assign template data 
		*/
		$this->_arrTemplateData['limit'] = $this->_arrConfig['limit'];
		$this->_arrTemplateData['page'] = $this->_arrConfig['page'];
		$this->_arrTemplateData['offset'] = $intOffset;
		$this->_arrTemplateData['found_rows'] = $intFoundRows;
		$this->_arrTemplateData['total_pages'] = $intFoundRows < $this->_arrConfig['limit']?1:ceil($intFoundRows/$this->_arrConfig['limit']);
		$this->_arrTemplateData['visible_pages'] = $this->_arrConfig['visiblePages'];
		$this->_arrTemplateData['base_path'] = $this->_arrConfig['basePath'];
		$this->_arrTemplateData['label'] = $this->_arrConfig['label'];
		$this->_arrTemplateData['page_flag'] = $this->_arrConfig['pageFlag'];
		
		/*
		* Return the pagination template 
		*/
		return $this->display();
	}
	
	public function display() {
		extract($this->_arrTemplateData);
		
		if($total_pages <= $visible_pages) {
    		$page_start = 1;
    		$page_end = $total_pages;
		} else if($page <= ceil($visible_pages/2)) {
    		$page_start = 1;
    		$page_end = $visible_pages;
		} else if($page > ($total_pages - ceil($visible_pages/2))) {
    		$page_start = $total_pages - (ceil(($visible_pages/2)*2)-1);
    		$page_end = $total_pages;
		} else {
    		$page_start = $page-(floor($visible_pages/2));
    		$page_end = $page+(floor($visible_pages/2));
		}
		
		$return = sprintf(
   			'<div class="summary"><p class="pages">&#37;u %s</p><p class="total">%u %s</p></div>'
    		,$total_pages
    		,$total_pages == 1?'Page':'Pages'
    		,$found_rows
    		,$found_rows == 1?$label:$label
		);
		
		$return.= sprintf('<ul class="pagination">');
		$return.= sprintf(
    		'<li class="first">%s%s%s</li>'
    		,$page == 1?'':sprintf('<a href="%s">',str_replace($page_flag,1,$base_path))
    		,'First'
    		,$page == 1?'':'</a>'
		);    
		$return.= sprintf(
    		'<li class="previous">%s%s%s</li>'
   		 	,$page == 1?'':sprintf('<a href="%s">',str_replace($page_flag,($page-1),$base_path))
    		,'Previous'
    		,$page == 1?'':'</a>'
		);
		foreach(range($page_start,$page_end,1) as $i) {
    		$return.= sprintf(
        		'<li%s>%s%s%s</li>'
        		,$page == $i?' class="current"':''
        		,$page == $i?'':sprintf('<a href="%s">',str_replace($page_flag,$i,$base_path))
        		,$i
        		,$page == $i?'':'</a>'
    		);
		}
		$return.= sprintf(
			'<li class="next">%s%s%s</li>'
			,$page == $total_pages?'':sprintf('<a href="%s">',str_replace($page_flag,($page+1),$base_path))
    		,'Next'
    		,$page == $total_pages?'':'</a>'
		);
		$return.= sprintf(
    		'<li class="last">%s%s%s</li>'
    		,$page == $total_pages?'':sprintf('<a href="%s">',str_replace($page_flag,$total_pages,$base_path))
    		,'Last'
    		,$page == $total_pages?'':'</a>'
		);
		$return.= sprintf('</ul>');
		
		return $return;
		
	}

}

define('PADU_NOTICE','table_name');

class Action {

	public function paginate($offset,$limit) {
		
		// run query and assign returned data for listing
		echo "<p>SELECT * FROM ".PADU_NOTICE." WHERE DEPARTMENT_CODE='04'</p>";
		
		// return number of total found rows
		return 400;
	
	}

}

$action = new Action();

$func = create_function('$offset,$limit,$action','return $action->paginate($offset,$limit);');
$pg = new Pagination($func,array(
	'basePath'=>$_SERVER['PHP_SELF'].'?p={replace_me_with_page}'
	,'pageFlag'=>'{replace_me_with_page}'
	,'label'=>'Departments'
	,'limit'=>5
	,'page'=>isset($_GET['p']) && is_numeric($_GET['p']) && $_GET['p'] != 0?$_GET['p']:1
	,'visiblePages'=>10
),array($action));

echo $pg->paginate();

?>