Selectable Items per Page Hack for Drupal 6 Views

I’m sure regular contributors to Drupal will cringe at what I’m about to show you, but I found it to be a handy trick. Let’s say you’re using the Views module in Drupal 6 and you want a way to dynamically control the number of items listed in a view. In my case, a client I was working for wanted to be able to select the number of products displayed per page.

Reasonable request, right? Unfortunately, Views doesn’t handle it out of the box. After a bit of fiddling, I managed to come up with the following hack. Mind you, I use the term “hack” here literally; you should never edit a module like this if you can avoid it, if only because it makes updates painful later on.

The operative code is in the pre_execute() function on line 1795 of modules/plugins/views_plugin_display.inc. It normally looks like this:

$this->view->set_items_per_page($this->get_option('items_per_page'));

As the name suggests, anything you feed to this function will set the number of items displayed by the view. In my case, I wanted to use a URL variable coupled with a drop-down menu and some jQuery to toggle it, so I changed it like so:

$this->view->set_items_per_page((($_GET['items-per-page'] > 0) ? $_GET['items-per-page'] : $this->get_option('items_per_page')));

Voila! One line of code and you’re off to the races. Type ‘?items-per-page=X’ into the URL (with X being a number, of course) and it should work like a charm. The pagination even follows suit.

For those who want the full solution, here’s the code for the drop-down menu. You’ll need to add it to a view-specific template file. Just follow the pattern to create your own items per page options.

<?php $items_per_page_override = ($_GET['items-per-page'] > 0) ? $_GET['items-per-page'] : 12; ?>
<div id="items-per-page-selector"><strong>Items per Page:</strong> <select>
<option value="12"<?php echo ($items_per_page_override == 12) ? ' selected="selected"' : ''; ?>>12</option>
<option value="18"<?php echo ($items_per_page_override == 18) ? ' selected="selected"' : ''; ?>>18</option>
<option value="24"<?php echo ($items_per_page_override == 24) ? ' selected="selected"' : ''; ?>>24</option>
<option value="9999"<?php echo ($items_per_page_override == 9999) ? ' selected="selected"' : ''; ?>>All</option>
</select>

And here is the jQuery that controls the behavior of the drop-down menu.

$(document).ready(function(){
$('#items-per-page-selector select').change(function(){
window.location = '?items-per-page=' + $(this).val();
});
});

Comments

10 Responses to “Selectable Items per Page Hack for Drupal 6 Views”

  1. bronius on March 1st, 2010 4:28 pm

    Note: I think it’s possible to override this value without a .module hack, at least in the case of embedded views. In the case of embedded views, I believe you could simply set $view->set_items_per_page just like you did in your hack but in the embed.

  2. jberg on December 16th, 2010 3:22 pm

    Would it also be possible to override the function in the theme template.php file so you didn’t have to hack the module? sites/all/themes/theme_name/template.php
    Then it would be specific for the theme on a server running multiple Drupal sites.

    Either way, great solution. Surprised someone hasn’t added something like this to views>pager. It would nice to have a “user defined” option, or at least a “view all” option.

  3. Stephen Ward on January 1st, 2011 11:29 am

    That could be a possible solution, jberg, although I’m not sure if that function can be overridden from template.php. I’ve never tried it that way, but I imagine it’s possible; pretty much everything in Drupal can be overridden one way or another.

  4. titouille on January 11th, 2011 11:27 am

    Another solution I found with your suggestion is to use the hook_views_pre_execute to modify the item_per_page value like this :

    function mymodule_views_pre_execute( &$view ) {

    if( $view->name == “my_view” ) {

    $display = $view->current_display;

    if( $view->display[$display]->display_title == “All my blog posts” ) {

    $limit = 12;
    if( isset( $_GET["limit"] ) ) $limit = $_SESSION['limit'] = $_GET["limit"];
    else if( isset( $_SESSION['limit'] ) ) $limit = $_SESSION['limit'];

    if( intval( $limit ) == 0 )
    $limit = 12;

    $view->set_items_per_page( $limit );
    }
    }

    Hope this help ;-)

  5. Dornelas on May 1st, 2011 6:18 am

    You guys saved me a lot of time. Thank you very much.
    titouille’s solution works very well.

  6. Garry on May 24th, 2011 4:10 am

    Another version of titoulle’s answer is to have this in a custom module:

    function yourmodulename_views_pre_execute(&$view){
    if ($view->name == ‘yourviewname’) {

    $view->set_items_per_page((($_GET['items-per-page'] > 0) ? $_GET['items-per-page'] : $view->get_option(‘items_per_page’)));

    }

    }

    This code is just slightly different from the one above, I didn’t have need to code in the limit amount or use SESSION variables.

    Hope this helps anyone who needs it.

  7. Garry on May 24th, 2011 4:47 am

    EDIT:

    Sorry I hadn’t fully tested that code: here is the working code:

    module:

    function yourmodulename_views_pre_execute(&$view){
    if ($view->name == ‘yourviewname’) {

    $view->set_items_per_page((($_GET['items-per-page'] > 0) ? $_GET['items-per-page'] : ”));

    }

    }

  8. Erald on July 5th, 2011 5:32 am

    I like the solution but had some problems with blocks which do not use a pager. so changed things a bit so views on the same page which are not using a pager will not be affected.

    ?get_option(‘use_pager’) == ’0′) {
    $this->view->set_items_per_page($this->get_option(‘items_per_page’));
    } else {
    $this->view->set_items_per_page((($_GET['items-per-page'] > 0) ? $_GET['items-per-page'] : $this->get_option(‘items_per_page’)));
    }
    ?>

    Tried to make a module but probably I am doing something wrong somewhere since got all kinds of weird things. If someone has the complete module code I would appreciate it since hate to hack into the core code.

  9. Erald on July 5th, 2011 10:37 am

    hmm something went wrong with the pasting

    the correct code which works
    if ($this->get_option(‘use_pager’) == ’0′) {
    $this->view->set_items_per_page($this->get_option(‘items_per_page’));
    } else {
    $this->view->set_items_per_page((($_GET['items-per-page'] > 0) ? $_GET['items-per-page'] : $this->get_option(‘items_per_page’)));
    }

  10. Stephen Ward on July 16th, 2011 12:17 pm

    All good solutions. Interestingly enough, the D7 version of Views exposed the items per page filter, so it seems this will always be a backwards hack. Yay for open source!

Share Your Thoughts