Actions

J1.5

Difference between revisions of "Using JPagination in your component"

From Joomla! Documentation

(New page: {{inuse}} ==Introduction== The JPagination class, introduced in Joomla! 1.5, allows developers to reliably and consistently adding pagination to the Front-end and Back-end display of their...)
 
(Implementing Pagination in Front End)
(19 intermediate revisions by 9 users not shown)
Line 1: Line 1:
{{inuse}}
+
{{incomplete}}
==Introduction==
+
The JPagination class, introduced in Joomla! 1.5, allows developers to reliably and consistently adding pagination to the Front-end and Back-end display of their components.
+
  
 +
{{RightTOC}}
 +
==Class Overview==
 +
The JPagination class, introduced in Joomla! 1.5, allows developers to reliably and consistently add pagination to the Front-end and Back-end display of their components.  The file containing the class can be found at /libraries/joomla/html/pagination.php. 
  
==Changes to the Model==
+
====Variables====
 +
The construct function of the class requires three variables:
 +
* $total - the total number of items in a list,
 +
* $limitstart - the offset of the item at which to start, and
 +
* $limit - the number of items to display per page.
 +
 
 +
====Static Class Methods====
 +
=====getRowOffset($index)=====
 +
 
 +
=====getData()=====
 +
 
 +
=====getPagesCounter()=====
 +
<source lang="php">
 +
/**
 +
* Create and return the pagination pages counter string
 +
*
 +
* @access public
 +
* @return string Pagination pages counter string
 +
* @since 1.5
 +
*/
 +
function getPagesCounter()
 +
</source>
 +
 
 +
Returns a string containing the current page and total pages as [[image:pagescounter.png]]
 +
 
 +
=====getResultsCounter()=====
 +
<source lang="php">
 +
/**
 +
* Create and return the pagination result set counter string
 +
*
 +
* @access public
 +
* @return string Pagination result set counter string
 +
* @since 1.5
 +
*/
 +
function getResultsCounter()
 +
</source>
 +
 
 +
Returns a string containing the results currently being displayed as [[image:resultscounter.png]]
 +
 
 +
=====getPagesLinks()=====
 +
<source lang="php">
 +
/**
 +
* Create and return the pagination page list string, ie. Previous, Next, 1 2 3 ... x
 +
*
 +
* @access public
 +
* @return string Pagination page list string
 +
* @since 1.0
 +
*/
 +
function getPagesLinks()
 +
</source>
 +
 
 +
Returns an HTML string to display the Pages Links as [[image:pageslinks.png]]
 +
 
 +
=====getListFooter()=====
 +
<source lang="php">
 +
/**
 +
* Return the pagination footer
 +
*
 +
* @access public
 +
* @return string Pagination footer
 +
* @since 1.0
 +
*/
 +
function getListFooter()
 +
</source>
 +
 
 +
Returns a combination of the several page-related elements, including: the Display Limit dropdown, the Pages Links and the Pages Counter.  Appearance differs in the Front-end and Back-end due to additional CSS formatting applied with the Khepri template.
 +
 
 +
Front-end: [[image:listfooter-front.png]]
 +
 
 +
Back-end: [[image:pagination.png]]
 +
 
 +
=====getLimitBox()=====
 +
<source lang="php">
 +
/**
 +
* Creates a dropdown box for selecting how many records to show per page
 +
*
 +
* @access public
 +
* @return string The html for the limit # input box
 +
* @since 1.0
 +
*/
 +
function getLimitBox()
 +
</source>
 +
 
 +
Returns an HTML string that will output the Display Limit dropdown as [[image:limitbox.png]]
 +
 
 +
=====orderUpIcon()=====
 +
 
 +
=====orderDownIcon()=====
 +
 
 +
==Examples==
 +
 
 +
===with JDatabase===
 +
Here is a nice method that uses the strength of mysql who knows pagination too.  Really!
 +
 
 +
''Most developers don't use the SQL_CALC_FOUND_ROWS and just double the query without limit.  Just don't!! ;-)''
 +
<source lang="php">
 +
$db =& JFactory::getDBO();
 +
$lim = $mainframe->getUserStateFromRequest("$option.limit", 'limit', 14, 'int'); //I guess getUserStateFromRequest is for session or different reasons
 +
$lim0 = JRequest::getVar('limitstart', 0, '', 'int');
 +
$db->setQuery('SELECT SQL_CALC_FOUND_ROWS x, y, z FROM jos_content WHERE x',$lim0, $lim);
 +
$rL=&$db->loadAssocList();
 +
if (empty($rL)) {$jAp->enqueueMessage($db->getErrorMsg(),'error'); return;}
 +
else {
 +
////Here the beauty starts
 +
$db->setQuery('SELECT FOUND_ROWS();');  //no reloading the query! Just asking for total without limit
 +
jimport('joomla.html.pagination');
 +
$pageNav = new JPagination( $db->loadResult(), $lim0, $lim );
 +
foreach($rL as $r) {
 +
//your display code here
 +
}
 +
echo $pageNav->getListFooter(  ); //Displays a nice footer
 +
</source>
 +
 
 +
==Implementation==
 +
====Changes to the Model====
 
Declare $_total and $_pagination variables in the model; these will be returned by the functions getTotal() and getPagination(), respectively.
 
Declare $_total and $_pagination variables in the model; these will be returned by the functions getTotal() and getPagination(), respectively.
<pre>
+
<source lang="php">
 
   /**
 
   /**
 
   * Items total
 
   * Items total
Line 18: Line 133:
 
   */
 
   */
 
   var $_pagination = null;
 
   var $_pagination = null;
</pre>
+
</source>
  
 
Add to or create a __construct() function that will establish values for the $limitstart and $limit variables as these are needed by the JPagination class.
 
Add to or create a __construct() function that will establish values for the $limitstart and $limit variables as these are needed by the JPagination class.
<pre>
+
<source lang="php">
 
   function __construct()
 
   function __construct()
 
   {
 
   {
 
  parent::__construct();
 
  parent::__construct();
  
global $mainframe, $option;
+
$mainframe = JFactory::getApplication();
  
 
// Get pagination request variables
 
// Get pagination request variables
 
$limit = $mainframe->getUserStateFromRequest('global.list.limit', 'limit', $mainframe->getCfg('list_limit'), 'int');
 
$limit = $mainframe->getUserStateFromRequest('global.list.limit', 'limit', $mainframe->getCfg('list_limit'), 'int');
$limitstart = $mainframe->getUserStateFromRequest($option.'.limitstart', 'limitstart', 0, 'int');
+
$limitstart = JRequest::getVar('limitstart', 0, '', 'int');
  
 
// In case limit has been changed, adjust it
 
// In case limit has been changed, adjust it
Line 38: Line 153:
 
$this->setState('limitstart', $limitstart);
 
$this->setState('limitstart', $limitstart);
 
   }
 
   }
</pre>
+
</source>
  
 
Revise the getData() function, adding the $limitstart and $limit values to the _getList() query.  This causes only the needed rows to be returned, rather than all rows.  
 
Revise the getData() function, adding the $limitstart and $limit values to the _getList() query.  This causes only the needed rows to be returned, rather than all rows.  
<pre>
+
<source lang="php">
 
   function getData()  
 
   function getData()  
 
   {
 
   {
Line 51: Line 166:
 
  return $this->_data;
 
  return $this->_data;
 
   }
 
   }
</pre>
+
</source>
  
 
Create a getTotal() function.  This function uses the _getListCount() method from JModel to return the total number of rows in the query.  The value returned will be used by the getPagination() function.
 
Create a getTotal() function.  This function uses the _getListCount() method from JModel to return the total number of rows in the query.  The value returned will be used by the getPagination() function.
<pre>
+
<source lang="php">
 
   function getTotal()
 
   function getTotal()
 
   {
 
   {
Line 60: Line 175:
 
  if (empty($this->_total)) {
 
  if (empty($this->_total)) {
 
      $query = $this->_buildQuery();
 
      $query = $this->_buildQuery();
      $this->_total = $this->_getListCount($query); // _getListCount is from JModel class
+
      $this->_total = $this->_getListCount($query);
 
  }
 
  }
 
  return $this->_total;
 
  return $this->_total;
 
   }
 
   }
</pre>
+
</source>
  
 
Create a getPagination() function.  The function will create and return a new Pagination object that can be accessed by the View.
 
Create a getPagination() function.  The function will create and return a new Pagination object that can be accessed by the View.
<pre>
+
<source lang="php">
 
   function getPagination()
 
   function getPagination()
 
   {
 
   {
Line 77: Line 192:
 
  return $this->_pagination;
 
  return $this->_pagination;
 
   }
 
   }
</pre>
+
</source>
  
 
+
====Changes to the View====
==Changes to the View==
+
 
Revise the View to obtain the pagination object created in the Model and assign it for use in the template.
 
Revise the View to obtain the pagination object created in the Model and assign it for use in the template.
<pre>
+
<source lang="php">
 
   ...
 
   ...
 
   // Get data from the model
 
   // Get data from the model
Line 92: Line 206:
 
$this->assignRef('pagination', $pagination);
 
$this->assignRef('pagination', $pagination);
 
   ...
 
   ...
</pre>
+
</source>
  
  
==Changes to the Template==
+
====Changes to the Template====
 
Add a footer area to the display table in the template which holds the pagination object.  The method getListFooter() from the JPagination class generates the buttons and their next/previous functionality as shown in the image above.  Edit colspan="9" to reflect the number of columns in the table.
 
Add a footer area to the display table in the template which holds the pagination object.  The method getListFooter() from the JPagination class generates the buttons and their next/previous functionality as shown in the image above.  Edit colspan="9" to reflect the number of columns in the table.
<pre>
+
<source lang="php">
 
   ...
 
   ...
 
   <tfoot>
 
   <tfoot>
Line 105: Line 219:
 
   </tfoot>
 
   </tfoot>
 
   ...
 
   ...
</pre>
+
</source>
 +
 
 +
Then you have to put another hidden input in your adminform.
 +
in your "default.php" add this to form:
 +
<source lang="php">
 +
  ...
 +
  <input type="hidden" name="view" value="your_view_name" />
 +
  ...
 +
</source>
 +
This is to tell Joomla! to redirect to "your_view_name" view after changing pagination.
 +
==Implementing Pagination in Front End==
 +
To be able to use Joomla!'s handy JPagination in the front end you need to import Joomla! modellist library into your model first, and extend JModelList class just as you would in the back end
 +
 
 +
<source lang="php">
 +
// import the Joomla modellist library
 +
jimport('joomla.application.component.modellist');
 +
 
 +
 
 +
 +
</source>
 +
 
 +
Then extend the JModelList class
 +
 
 +
<source lang="php">
 +
class ComponentnameModelModelName extends JModelList
 +
{
 +
/**
 +
* Method to build an SQL query to load the list data.
 +
*
 +
* @return string An SQL query
 +
*/
 +
protected function getListQuery()
 +
{
 +
// Create a new query object.
 +
$db = JFactory::getDBO();
 +
$query = $db->getQuery(true);
 +
// Select some fields
 +
$query->select('*');
 +
// From the tablename
 +
$query->from('#__tablename');
 +
return $query;
 +
}
 +
}
 +
</source>
 +
 
 +
Most of the hard work is already done for you by Joomla!. You only have to extend the above class and add the getListQuery() method that helps you build the query in which the pagination will  be based.
 +
 
 +
Pagination  methods, like getPagination(), getItems() & getListFooter() that will be called later from your view are already defined in the parent class of the subclass above.
 +
 
 +
===view.html.php===
 +
<source>
 +
// import Joomla view library
 +
jimport('joomla.application.component.view');
 +
 +
/**
 +
* Trainings View
 +
*/
 +
class ComponentNameViewViewName extends JView
 +
{
 +
/**
 +
*
 +
*/
 +
function display($tpl = null)
 +
{
 +
// Get data from the model
 +
$items = $this->get('Items');
 +
$pagination = $this->get('Pagination');
 +
 +
// Check for errors.
 +
if (count($errors = $this->get('Errors')))
 +
{
 +
JError::raiseError(500, implode('<br />', $errors));
 +
return false;
 +
}
 +
// Assign data to the view
 +
$this->items = $items;
 +
$this->pagination = $pagination;
 +
 +
 +
// Display the template
 +
parent::display($tpl);
 +
 +
}
 +
</source>
 +
===default.php===
 +
Assuming that we are using default template for the view, the following code will generate output with pagination ready in the front end;
 +
<source lang="php">
 +
<?php
 +
// No direct access to this file
 +
defined('_JEXEC') or die('Restricted Access');
 +
// load tooltip behavior
 +
JHtml::_('behavior.tooltip');
 +
?>
 +
<form action="<?php echo JRoute::_('index.php?option=com_ComponentName'); ?>" method="post" name="adminForm">
 +
 
 +
// ITEMS FROM THE DATABASE GO HERE!!!!
 +
 
 +
// PAGINATION GOES HERE
 +
<?php echo $this->pagination->getListFooter(); ?>
 +
</form>
 +
</source>
 +
 
 +
Remember tor wrap the output in a form.
 +
[[Category:Component Development]]
 +
[[Category:Tutorials]]

Revision as of 12:00, 13 December 2012

Replacement filing cabinet.png
This Namespace has been archived - Please Do Not Edit or Create Pages in this namespace. Pages contain information for a Joomla! version which is no longer supported. It exists only as a historical reference, will not be improved and its content may be incomplete.
Quill icon.png
Content is Incomplete

This article or section is incomplete, which means it may be lacking information. You are welcome to assist in its completion by editing it as well. If this article or section has not been edited in several days, please consider helping complete the content.
This article was last edited by Mburucharles (talk| contribs) 20 months ago. (Purge)


Contents

Class Overview

The JPagination class, introduced in Joomla! 1.5, allows developers to reliably and consistently add pagination to the Front-end and Back-end display of their components. The file containing the class can be found at /libraries/joomla/html/pagination.php.

Variables

The construct function of the class requires three variables:

  • $total - the total number of items in a list,
  • $limitstart - the offset of the item at which to start, and
  • $limit - the number of items to display per page.

Static Class Methods

getRowOffset($index)
getData()
getPagesCounter()
        /**
         * Create and return the pagination pages counter string
         *
         * @access      public
         * @return      string  Pagination pages counter string
         * @since       1.5
         */
        function getPagesCounter()

Returns a string containing the current page and total pages as Pagescounter.png

getResultsCounter()
        /**
         * Create and return the pagination result set counter string
         *
         * @access      public
         * @return      string  Pagination result set counter string
         * @since       1.5
         */
        function getResultsCounter()

Returns a string containing the results currently being displayed as Resultscounter.png

getPagesLinks()
        /**
         * Create and return the pagination page list string, ie. Previous, Next, 1 2 3 ... x
         *
         * @access      public
         * @return      string  Pagination page list string
         * @since       1.0
         */
        function getPagesLinks()

Returns an HTML string to display the Pages Links as Pageslinks.png

getListFooter()
        /**
         * Return the pagination footer
         *
         * @access      public
         * @return      string  Pagination footer
         * @since       1.0
         */
        function getListFooter()

Returns a combination of the several page-related elements, including: the Display Limit dropdown, the Pages Links and the Pages Counter. Appearance differs in the Front-end and Back-end due to additional CSS formatting applied with the Khepri template.

Front-end: Listfooter-front.png

Back-end: Pagination.png

getLimitBox()
        /**
         * Creates a dropdown box for selecting how many records to show per page
         *
         * @access      public
         * @return      string  The html for the limit # input box
         * @since       1.0
         */
        function getLimitBox()

Returns an HTML string that will output the Display Limit dropdown as Limitbox.png

orderUpIcon()
orderDownIcon()

Examples

with JDatabase

Here is a nice method that uses the strength of mysql who knows pagination too. Really!

Most developers don't use the SQL_CALC_FOUND_ROWS and just double the query without limit. Just don't!! ;-)

$db =& JFactory::getDBO();
$lim    = $mainframe->getUserStateFromRequest("$option.limit", 'limit', 14, 'int'); //I guess getUserStateFromRequest is for session or different reasons
$lim0   = JRequest::getVar('limitstart', 0, '', 'int');
$db->setQuery('SELECT SQL_CALC_FOUND_ROWS x, y, z FROM jos_content WHERE x',$lim0, $lim);
$rL=&$db->loadAssocList();
if (empty($rL)) {$jAp->enqueueMessage($db->getErrorMsg(),'error'); return;}     
else {
////Here the beauty starts
$db->setQuery('SELECT FOUND_ROWS();');  //no reloading the query! Just asking for total without limit
jimport('joomla.html.pagination');
$pageNav = new JPagination( $db->loadResult(), $lim0, $lim );
foreach($rL as $r) {
//your display code here
}
echo $pageNav->getListFooter(  ); //Displays a nice footer

Implementation

Changes to the Model

Declare $_total and $_pagination variables in the model; these will be returned by the functions getTotal() and getPagination(), respectively.

  /**
   * Items total
   * @var integer
   */
  var $_total = null;
 
  /**
   * Pagination object
   * @var object
   */
  var $_pagination = null;

Add to or create a __construct() function that will establish values for the $limitstart and $limit variables as these are needed by the JPagination class.

  function __construct()
  {
        parent::__construct();
 
        $mainframe = JFactory::getApplication();
 
        // Get pagination request variables
        $limit = $mainframe->getUserStateFromRequest('global.list.limit', 'limit', $mainframe->getCfg('list_limit'), 'int');
        $limitstart = JRequest::getVar('limitstart', 0, '', 'int');
 
        // In case limit has been changed, adjust it
        $limitstart = ($limit != 0 ? (floor($limitstart / $limit) * $limit) : 0);
 
        $this->setState('limit', $limit);
        $this->setState('limitstart', $limitstart);
  }

Revise the getData() function, adding the $limitstart and $limit values to the _getList() query. This causes only the needed rows to be returned, rather than all rows.

  function getData() 
  {
        // if data hasn't already been obtained, load it
        if (empty($this->_data)) {
            $query = $this->_buildQuery();
            $this->_data = $this->_getList($query, $this->getState('limitstart'), $this->getState('limit'));    
        }
        return $this->_data;
  }

Create a getTotal() function. This function uses the _getListCount() method from JModel to return the total number of rows in the query. The value returned will be used by the getPagination() function.

  function getTotal()
  {
        // Load the content if it doesn't already exist
        if (empty($this->_total)) {
            $query = $this->_buildQuery();
            $this->_total = $this->_getListCount($query);       
        }
        return $this->_total;
  }

Create a getPagination() function. The function will create and return a new Pagination object that can be accessed by the View.

  function getPagination()
  {
        // Load the content if it doesn't already exist
        if (empty($this->_pagination)) {
            jimport('joomla.html.pagination');
            $this->_pagination = new JPagination($this->getTotal(), $this->getState('limitstart'), $this->getState('limit') );
        }
        return $this->_pagination;
  }

Changes to the View

Revise the View to obtain the pagination object created in the Model and assign it for use in the template.

  ...
        // Get data from the model
        $items =& $this->get('Data');   
        $pagination =& $this->get('Pagination');
 
        // push data into the template
        $this->assignRef('items', $items);      
        $this->assignRef('pagination', $pagination);
  ...


Changes to the Template

Add a footer area to the display table in the template which holds the pagination object. The method getListFooter() from the JPagination class generates the buttons and their next/previous functionality as shown in the image above. Edit colspan="9" to reflect the number of columns in the table.

  ...
  <tfoot>
    <tr>
      <td colspan="9"><?php echo $this->pagination->getListFooter(); ?></td>
    </tr>
  </tfoot>
  ...

Then you have to put another hidden input in your adminform. in your "default.php" add this to form:

  ...
  <input type="hidden" name="view" value="your_view_name" />
  ...

This is to tell Joomla! to redirect to "your_view_name" view after changing pagination.

Implementing Pagination in Front End

To be able to use Joomla!'s handy JPagination in the front end you need to import Joomla! modellist library into your model first, and extend JModelList class just as you would in the back end

 // import the Joomla modellist library
jimport('joomla.application.component.modellist');

Then extend the JModelList class

class ComponentnameModelModelName extends JModelList
{
        /**
         * Method to build an SQL query to load the list data.
         *
         * @return      string  An SQL query
         */
        protected function getListQuery()
        {
                // Create a new query object.           
                $db = JFactory::getDBO();
                $query = $db->getQuery(true);
                // Select some fields
                $query->select('*');
                // From the tablename
                $query->from('#__tablename');
                return $query;
        }
}

Most of the hard work is already done for you by Joomla!. You only have to extend the above class and add the getListQuery() method that helps you build the query in which the pagination will be based.

Pagination methods, like getPagination(), getItems() & getListFooter() that will be called later from your view are already defined in the parent class of the subclass above.

view.html.php

// import Joomla view library
jimport('joomla.application.component.view');
 
/**
 * Trainings View
 */
class ComponentNameViewViewName extends JView
{
        /**
         * 
         */
        function display($tpl = null) 
        {
                // Get data from the model
                $items = $this->get('Items');
                $pagination = $this->get('Pagination');
 
                // Check for errors.
                if (count($errors = $this->get('Errors'))) 
                {
                        JError::raiseError(500, implode('<br />', $errors));
                        return false;
                }
                // Assign data to the view
                $this->items = $items;
                $this->pagination = $pagination;
 
 
                // Display the template
                parent::display($tpl);
 
        }

default.php

Assuming that we are using default template for the view, the following code will generate output with pagination ready in the front end;

<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted Access');
// load tooltip behavior
JHtml::_('behavior.tooltip');
?>
<form action="<?php echo JRoute::_('index.php?option=com_ComponentName'); ?>" method="post" name="adminForm">
 
//      ITEMS FROM THE DATABASE GO HERE!!!!
 
// PAGINATION GOES HERE
<?php echo $this->pagination->getListFooter(); ?>
</form>

Remember tor wrap the output in a form.