Janith Widarshana
Janith Widarshana

Reputation: 3483

joomla 2.5 pagination always set start limit to 20

I developed my own joomla 2.5 custom component for displaying data table in front-end.It contain filtering,paging and sorting.When navigate via paging it always shows only first 20. Is there any way to override limit of a query which generate on function getListQuery().

My populateState method is

protected function populateState($ordering = null, $direction = null) {
        // Initialise variables.
        $app = JFactory::getApplication();

        $search = $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search');
        $filter_order = $this->getUserStateFromRequest($this->context . '.filter_order', 'filter_order');
        //$filter_order = JRequest::getCmd('filter_order');
        $filter_order_Dir = $this->getUserStateFromRequest($this->context . '.filter_order_Dir', 'filter_order_Dir');
        //$filter_order_Dir = JRequest::getCmd('filter_order_Dir');

        'filter_region', '');

        $this->setState('filter_order', $filter_order);
        $this->setState('filter_order_Dir', $filter_order_Dir);


        // List state information
        $limit = $app->getUserStateFromRequest('global.list.limit', 'limit', $app->getCfg('list_limit'));
        $this->setState('list.limit', $limit);

        $limitstart = JRequest::getVar('limitstart', 0, '', 'int');
        $this->setState('list.start', $limitstart);

        parent::populateState();
    } 

Constructor method is

    function __construct() {
            parent::__construct();


            //Get configuration
            $app = JFactory::getApplication();
            $config = JFactory::getConfig();

            // Get the pagination request variables
            $this->setState('limit', $app->getUserStateFromRequest('com_jointcm.limit', 'limit', $config->getValue('config.list_limit'), 'int'));
            $this->setState('limitstart', JRequest::getVar('limitstart', 0, '', 'int'));
    }

List query method is

protected function getListQuery() {
        // Create a new query object.
        $db = JFactory::getDBO();
        $query = $db->getQuery(true);
 //code goes here...
..............

return $query;
}

Upvotes: 0

Views: 7580

Answers (4)

Craig
Craig

Reputation: 9330

In JModelList's getItems() the default method uses getStart() which in turn uses your models getQuery() to get a count of the number of items returned by your query, via _getListCount($query) which in turn calls the particular database adaptors version of getNumRows()). That value is used in the calculation in getStart(), if you have a large complicated query and don't really need to use the fancy getStart() implementation you can just override it in your model (i.e. your version of the JModelList class)

e.g. for our components model's for the front end which have rather complicated $query's returned by getListQuery, in their most basic implementation they do something similar to this:

public function getStart()
{
    return $this->getState('list.start');
}

If you don't override it the default JModelList getStart() is invoked which looks like this:

/**
 * Method to get the starting number of items for the data set.
 *
 * @return  integer  The starting number of items available in the data set.
 *
 * @since   11.1
 */
public function getStart()
{
    $store = $this->getStoreId('getstart');

    // Try to load the data from internal storage.
    if (isset($this->cache[$store]))
    {
        return $this->cache[$store];
    }

    $start = $this->getState('list.start');
    $limit = $this->getState('list.limit');
    $total = $this->getTotal();
    if ($start > $total - $limit)
    {
        $start = max(0, (int) (ceil($total / $limit) - 1) * $limit);
    }

    // Add the total to the internal cache.
    $this->cache[$store] = $start;

    return $this->cache[$store];
}

But, this probably isn't the problem area, it's more likely in your populateState(). At the end of populateState() you call parent::populateState() (if was called at the beginning it wouldn't be overwriting results of your method).

You seem to be duplicating the work done by the parent::populateState() which is probably redundant, looking at JModelList's implementation you will see this:

protected function populateState($ordering = null, $direction = null)
{
    // If the context is set, assume that stateful lists are used.
    if ($this->context)
    {
        $app = JFactory::getApplication();

        $value = $app->getUserStateFromRequest('global.list.limit', 'limit', $app->getCfg('list_limit'), 'uint');
        $limit = $value;
        $this->setState('list.limit', $limit);

        $value = $app->getUserStateFromRequest($this->context . '.limitstart', 'limitstart', 0);
        $limitstart = ($limit != 0 ? (floor($value / $limit) * $limit) : 0);
        $this->setState('list.start', $limitstart);

        // Check if the ordering field is in the white list, otherwise use the incoming value.
        $value = $app->getUserStateFromRequest($this->context . '.ordercol', 'filter_order', $ordering);
        if (!in_array($value, $this->filter_fields))
        {
            $value = $ordering;
            $app->setUserState($this->context . '.ordercol', $value);
        }
        $this->setState('list.ordering', $value);

        // Check if the ordering direction is valid, otherwise use the incoming value.
        $value = $app->getUserStateFromRequest($this->context . '.orderdirn', 'filter_order_Dir', $direction);
        if (!in_array(strtoupper($value), array('ASC', 'DESC', '')))
        {
            $value = $direction;
            $app->setUserState($this->context . '.orderdirn', $value);
        }
        $this->setState('list.direction', $value);
    }
    else
    {
        $this->setState('list.start', 0);
        $this->state->set('list.limit', 0);
    }
}

The most obvious condition in the parent::populateState() that causes list.start to be set to 0 is the very first line, which checks your object context value, it may be that something is going wrong there and your objects context value is equating to false. (I can't see context defined anywhere... so, it will try an guess/build a context value for you in __construct()).

However, it may also be in the way in which getUserSateFromRequest() is processing the values returned from your request, it's hard to tell with the code available.

Upvotes: 1

Janith Widarshana
Janith Widarshana

Reputation: 3483

After some digging around and taking a look at the source code of the JModelList class, I realized that problem is with \libraries\joomla\application\component\modellist.php file ,method name public function getItems(),line number 115.

I changed it to

public function getItems()
    {
        // Get a storage key.
        $store = $this->getStoreId();

        // Try to load the data from internal storage.
        if (isset($this->cache[$store]))
        {
            return $this->cache[$store];
        }

        // Load the list items.
        $query = $this->_getListQuery();
        //$items = $this->_getList($query, $this->getStart(), $this->getState('list.limit'));
$items = $this->_getList($query, $this->getState('limitstart'), $this->getState('list.limit'));

        // Check for a database error.
        if ($this->_db->getErrorNum())
        {
            $this->setError($this->_db->getErrorMsg());
            return false;
        }

        // Add the items to the internal cache.
        $this->cache[$store] = $items;

        return $this->cache[$store];
    }

Change was

$items = $this->_getList($query, $this->getStart(), $this->getState('list.limit'));

to

$items = $this->_getList($query, $this->getState('limitstart'), $this->getState('list.limit'));

It works fine.

Upvotes: 1

Brent Friar
Brent Friar

Reputation: 10609

Do you have list_limit defined in your component options? If not, then add a new parameter to your component options and call it list_limit. This will allow you to set your pagination limit to what ever you want in the component options.

Upvotes: 0

JTC
JTC

Reputation: 3464

You can add limit like this $query->limit('0,40'); in getListQuery() function

Upvotes: 0

Related Questions