Pagination , filtered lists and page number links

6 posts by 3 authors in: Forums > CMS Builder
Last Post: October 7   (RSS)

I have a number sections that present pagination that can be in large numbers. When I use a perPage value of 3-5 to preserve design, many of my sections may require dozens of pages to show all the content. Because the standard pagination code for page bottom just provides prev and next links, the user may need to click "next" many, many times to go through the actual list.

In order to provide the user some greater control, I incorporated code that creates number links for all of the pages (as long ago suggested on your site):

---------------

<?php
if (@!$_GET['page']): $current_page = "1";
else: $current_page = $_GET['page'];
endif; ?>
<?php foreach (range(1,$music_videosMetaData['totalPages']) as $page): ?>
<?php if ($page == $current_page): ?>
<strong><?php echo $page; ?></strong>
<?php else: ?>
<a href="?page=<?php echo $page; ?>"><?php echo $page; ?></a>
<?php endif ?>
<?php endforeach; ?>
</p>
<p>
<?php if ($music_videosMetaData['prevPage']): ?>
<a href="https://avisitwithjesus.com/<?php echo $music_videosMetaData['prevPageLink'] ?>"><span class="fa-solid fa-hand-point-left avwj_color"></span></a>
<?php else: ?>
<span class="fa-solid fa-hand-point-left"></span>

<?php endif ?>

<?php if ($music_videosMetaData['nextPage']): ?>
<a href="https://avisitwithjesus.com/<?php echo $music_videosMetaData['nextPageLink'] ?>"><span class="fa-solid fa-hand-point-right avwj_color"></span></a>
<?php else: ?>
<span class="fa-solid fa-hand-point-right"></span>
</p>
<?php endif ?>

This code works fine in the basic situation. However, if one is also providing users search tools at the page top to filter the list, the numbering system breaks down.

If I allow a user to choose, for example, "category" from a dropdown and filter the list based upon this, a much smaller number of records is returned, along with the correspondingly diminished number of page links. However, these page links don't take the user to the indicated page number from among the filtered records, but rather the page number for the entire unfiltered list.

Does anyone have a suggestion as to how to modify the above code to take into account the filter criteria of the search?

Hello pgplast,

Besides passing just the page number in your links, you would pass along the additional filter criteria as well. Then on the page, you can used the passed criteria to query the data for the results and use that when setting up your pagination. I hope that makes sense. Since you don't pass along any of the filter data, just the page number, the query on the page doesn't know to filter the results and use that filtered data set as the basis of your pagination.

In the end you want $music_videosMetaData to be filled with the filtered results that was queried from the database using the values you passed along in the page links. For instance if you passed along a music artist name, you would pass page=2&artist=Cher so when the page loads it can use "Cher" to filter the results and then go to page 2.

Without knowing more about what fields you are dealing with, I can't provide additional code changes. I am hoping the explanation above would be enough to get you moving in the right direction. :)

Tim Hurd
Senior Web Programmer
Interactivetools.com

Hi All, 

Here's a slightly modified snippet of code from /lib/viewer_functions.php that generates page links and preserves the current URL values:

// duplicate current URL but with new page=# value
$pageNum  = 123;
$params   = array_merge($_REQUEST ?? [], ['page' => $pageNum]);
$pageLink = "?" . http_build_query($params, '', '&amp;');

Hope that helps!

Dave Edis - Senior Developer
interactivetools.com

Thanks, Tim.

And yes, that is what I had assumed. I have a <select> field called "music_category_match" on the page that supplies the "nums" from a table called music_category, a la:

<select name="music_category_match">
<option value="">Category</option>
<?php foreach ($music_categoryRecords as $music_categoryRecord): ?>
<option value="<?php echo $music_categoryRecord['num'] ?>"><?php echo $music_categoryRecord['category'] ?></option>
<?php endforeach ?>
</select>

When the user makes a selection and resubmits the page, a shorter list is returned as expected. However, the querystring  of the page does not show any $category value.

If I try to change the number links provided on the response page by adding a music_category (or Music_category_match) to the querystring nothing happens. e.g. 

<p>
<?php
if (@!$_GET['page']): $current_page = "1";
else: $current_page = $_GET['page'];
endif; ?>
<?php foreach (range(1,$music_videosMetaData['totalPages']) as $page): ?>
<?php if ($page == $current_page): ?>
<strong><?php echo $page; ?></strong>
<?php else: ?>
<?php if(@!$_GET['music_category_match']) { ?>
<a href="?page=<?php echo $page; ?>"><?php echo $page; ?></a>
<?php } else { ?>
<?php $cat = $_GET['music_category_match'];?>
<a href="?page=<?php echo $page; ?>&music_category_match=<?php echo $cat?>"><?php echo $page; ?></a>
<?php } // end if ?>
<?php endif ?>
<?php endforeach; ?>
</p>

I changed the head code to take into account the category value being sent in the querystring. but this never appears to happen

if(!isset($_GET['music_category_match'])) {
// load records from 'childers_videos'
list($music_videosRecords, $music_videosMetaData) = getRecords(array(
'tableName' => 'music_videos',
'perPage' => '3',
'loadUploads' => true,
'allowSearch' => true,
'orderBy' => 'title',
));


list($menu_listRecords, $menu_listMetaData) = getRecords(array(
'tableName' => 'music_videos',
'orderBy' => 'title',
'loadUploads' => false,
'allowSearch' => true,
));

} else {


$cat = $_GET['music_category_match'];


list($music_videosRecords, $music_videosMetaData) = getRecords(array(
'tableName' => 'music_videos',
'perPage' => '3',
'loadUploads' => true,
'allowSearch' => true,
'orderBy' => 'title',
'where' => 'music_category='.$cat,
));


list($menu_listRecords, $menu_listMetaData) = getRecords(array(
'tableName' => 'music_videos',
'orderBy' => 'title',
'loadUploads' => false,
'allowSearch' => true,
'where' => 'music_category='.$cat,
));

}

It appears that the music_category_match value never appears in a querystring. I am obviously not understanding this!

By Dave - October 7 - edited: October 7

Hi pgplast, 

Yea, the code you wrote looks pretty good at first glance.  

Sometimes it can also be clearer to just write the code in PHP (untested code): 

<?php
$current_page = empty($_GET['page']) ? "1" : $_GET['page'];

foreach (range(1, $music_videosMetaData['totalPages']) as $page) {
    // Show text only for the current page
    if ($page == $current_page) {
        echo "<strong>$page</strong>";
        continue;
    }

    // Show a link for all other pages
    $params   = array_merge($_REQUEST ?? [], ['page' => $page]);
    $pageLink = "?" . http_build_query($params, '', '&amp;');
    echo "<a href=\"$pageLink\">$page</a>";
}
?>

But if you have something working it might be easiest to just stick with that.

Hope that helps!

Dave Edis - Senior Developer
interactivetools.com