Jump to content

pagination never works


fruid
 Share

Recommended Posts

$limit = 12;
$start = $limit * ($input->pageNum() - 1);

$allcasts = pages("template=cast");

$casts = $allcasts->find("has_parent=$page, sort=$sort");
$casts = sortOutEmpty($casts, $decider);
$casts->setTotal($casts->count());
$casts->setStart($start);
$casts->setLimit($limit);

// just to test
echo $casts->getStart(); // 0 or 12 or 24 or 30 respectively
echo $casts->getLimit(); // 12
echo $casts->getTotal(); // 31 or whatever the total

echo casts($casts); // never mind this, it's just for markup creation and works fine
$pager->render($casts, $pagerOptions);

// I store the name of a specific field as a string in a variable so I can dynamically sort out content of which that field is empty in the current language 
function sortOutEmpty($items, $decider) {
    $casts = new PaginatedArray;
    foreach ($items as $item) :
        if ($item->$decider != '') :
            $casts->add($item);
        endif;
    endforeach;
    return $casts;
}

I get the right number of pages in the pager. Pager works but the results never paginate.

This pagination API is driving me nuts, it just doesn't work!
I can't be the only one who's having issues with this, it's hard to find any topic where issues are discussed and the API-documentation is, as usual, very laconic.

Thanks for help!

Link to comment
Share on other sites

If I start over and don't use any additional function, I need to put the

decider!=

in the selector which doesn't work.

Also, even if it did work in the classic way (which seems to be the only way), as opposed to building a custom PaginatedArray, it would solve the problem now but not in the long run. Building a custom PaginatedArray and then paginate it properly is almost impossible.

Link to comment
Share on other sites

I'm not sure about using pagination in other situations, but with Lister Pro, it breaks when Tracy Debugger is enabled. Disabling Tracy Debugger causes pagination to work again with Lister Pro.

I haven't tested with other scenarios, but if you have Tracy Debugger installed and enabled, and everything else with your pagination seems to be set up correctly, it might be worth disabling Tracy to see if that makes a difference.

  • Like 1
Link to comment
Share on other sites

8 hours ago, Kiwi Chris said:

I'm not sure about using pagination in other situations, but with Lister Pro, it breaks when Tracy Debugger is enabled. Disabling Tracy Debugger causes pagination to work again with Lister Pro.

I haven't tested with other scenarios, but if you have Tracy Debugger installed and enabled, and everything else with your pagination seems to be set up correctly, it might be worth disabling Tracy to see if that makes a difference.

nope, just tried. But thanks anyway.

$limit = 6;
$start = $limit * ($input->pageNum() - 1);
$decider = 'body';

$allcasts = pages("template=cast"); // 35
$matches = $allcasts->find("has_parent=$page, sort=$sort"); // 32
$casts = sortOutEmpty($matches, $decider); // 31
$total = $casts->count(); // 31
$casts->setStart($start); // 0 on page 1, 6 on page 2, 12 on page 3, …
$casts->setLimit($limit); // 6
$casts->setTotal($total); // 31
echo $casts->count(); // !!! 31 shouldn't that be 6 now that I set start and limit above? I thought ->count always returns the number of items on the current paginated page, not the total

function sortOutEmpty($items, $decider) {
    $out = new PaginatedArray;
    foreach ($items as $item) :
        if ($item->$decider != '') :
            $out->add($item);
        endif;
    endforeach;
    return $out;
}

the items are not paginated, meaning they are not distributed among several pages but they are always returned in total. This pagination API is just garbage, it just never works when you build a custom PaginatedArray.

Link to comment
Share on other sites

Not tested, written in browser... 

$allcasts = $pages->find("template=cast, has_parent=$page, sort=$sort");
$casts = sortOutEmpty($allcasts, $decider);

$limit = 6;
$start = $limit * ($input->pageNum() - 1);
$total = count($casts);

$casts->setTotal($total);
$casts->setLimit($limit);
$casts->setStart($start);

echo $casts->renderPager();


function sortOutEmpty($items, $decider) {
    $out = new PageArray();
    foreach ($items as $item) :
        if ($item->$decider != '') :
            $out->add($item);
        endif;
    endforeach;
    return $out;
}

  • Like 1
Link to comment
Share on other sites

@matjazp thanks for the suggestion, doesn't work either, just tried it.

The only difference I see in your code is count($casts) instead of $casts->count()

I think I also tried that before.

Link to comment
Share on other sites

    //$page->imge is PageImages with the total of 38 files
    $object = $page->imge;

    //total number of items, in this case total number of files in Images field
    $totalItems = count($object);

    //number of items to display per page
    $itemsPerPage = 5;

    //current page number, starting with 1, if no page specified, it defaults to 1
    $pageNum = $input->pageNum;

    //start item, depending on the current page number
    $startItem = ($pageNum - 1) * $itemsPerPage;

    //current items
    $items = $object->slice($startItem, $itemsPerPage);

    //debug info
    echo "totalItems=" . $totalItems . "<br>";
    echo "itemsPerPage=" . $itemsPerPage . "<br>";
    echo "pageNum=" . $pageNum . "<br>";
    echo "startItem=" . $startItem . "<br>";
    echo "<br>";

    //show info
    $start = $startItem + 1;
    $end = $start + count($items) - 1;
    $total = $totalItems;
    echo sprintf(__('%1$s %2$d to %3$d out of %4$d'), "Showing items ", $start, $end, $total);
    echo "<br><br>";

    //render items
    foreach($items as $item) {
        echo $item->name . "<br>";
    }
    echo "<br>";

    //create a new pageArray to give MarkupPagerNav what it needs
    $a = new PageArray();

    //tell the PageArray details it needs for pagination
    $a->setTotal($totalItems);
    $a->setLimit($itemsPerPage);
    $a->setStart($startItem);

    //show pager
    echo $a->renderPager(array('nextItemLabel' => ">",'previousItemLabel' => "<"));

 

renderPager.gif

  • Like 1
Link to comment
Share on other sites

18 hours ago, Kiwi Chris said:

I'm not sure about using pagination in other situations, but with Lister Pro, it breaks when Tracy Debugger is enabled.

Sorry, but I don't really think this is an accurate statement - I am running Tracy on many sites and it doesn't break pagination in Lister or in frontend templates on any of them. As discussed, I think there is something else going on with your setup and that JS error you are seeing that is contributing.

Link to comment
Share on other sites

8 hours ago, fruid said:

This pagination API is just garbage, it just never works when you build a custom PaginatedArray.

Have you read any of the linked posts from this thread: 

 

  • Like 1
Link to comment
Share on other sites

@adrian thanks but the linked topic is quite unrelated, I read through it, even the linked topics within in. I don't see how the approaches discussed can be helpful here. I'm not trying to merge two array objects, I'm trying to build an array object where a specific field is not empty and then paginate it.

I challenge whoever reads this to show me an example where a custom PaginatedArray is successfully paginated afterwards using ->setStart() ->setLimit() and ->setTotal() because I don't remember seeing it working. I always only succeeded by using selectors and never the methods.

Link to comment
Share on other sites

My apologies @fruid - I read this thread quickly and saw you comment about a custom paginated array and assumed that meant you were building up an array of pages rather than letting the pagination API handle querying the DB automatically. Sorry, I was in a rush and didn't fully grasp things. Good luck getting things sorted. I don't have time to dive deeper into this, but I guess I don't understand why you need to use the setStart() etc methods. I just build my selector and add a "limit=x" to it and that's it - everything else is automatic, but obviously I am not understanding your needs properly.

Link to comment
Share on other sites

Let's step back for a second.

I need to select pages where a certain field is empty.

$pages->find("template=cast, has_parent=$page, start=$start, limit=$limit, sort=$sort, body!=");

doesn't work

So I created a PaginatedArray and looped through the items. If the field (body) in question is empty add them to the PaginatedArray.

But then I – correct me if I'm wrong – need to use the ->setStart() ->setLimit() in order to paginate, which simply doesn't work.

That's all I need. If I get it sorted without the methods, good, but the methods remain to be proven functional.

Thanks! 

Link to comment
Share on other sites

$limit = 6;
$items = $pages->find("template=basic-page, limit=$limit, body!=''");

//alternative
/*
$decider = "body";
$items = $pages->find("template=basic-page, limit=5);
foreach($items as $item) {
  if($item->$decider != '') $items->remove($item);
}
*/

$start = $items->getStart() + 1;
$end = $start + count($items) - 1;
$total = $items->getTotal();

if($total) echo sprintf(__('%1$s %2$d to %3$d out of %4$d'), "Showing items ", $start, $end, $total)."<br><br>";

foreach($items as $item) echo $item->title . "<br>";
echo "<br>";
    
if ($items->getLimit() < $total) echo $items->renderPager();

 

  • Like 1
Link to comment
Share on other sites

Can you try this bare-bones example:

$pager = $modules->get('MarkupPagerNav');
$items = $pages->find("id>0, limit=10"); // replace id>0 with your selector
echo "<ul>" . $items->each("<li>{title}</li>") . "</ul>";
echo $pager->render($items); // render the pagination navigation

This works perfectly for me - each page has 10 results and each page starts where the last one stopped.

If that doesn't work, and you have pagination enabled for the template where you add this code, then I have no idea :)

Link to comment
Share on other sites

27 minutes ago, adrian said:

Can you try this bare-bones example:



$pager = $modules->get('MarkupPagerNav');
$items = $pages->find("id>0, limit=10"); // replace id>0 with your selector
echo "<ul>" . $items->each("<li>{title}</li>") . "</ul>";
echo $pager->render($items); // render the pagination navigation

This works perfectly for me - each page has 10 results and each page starts where the last one stopped.

If that doesn't work, and you have pagination enabled for the template where you add this code, then I have no idea :)

yes of course that works. But please, you try this now:

$items = $pages->find("id>1");
$home = $pages->get("id=1");

$customPaginatedArray = new PaginatedArray;
foreach ($items as $item) :
	if ($item->parent == $home) :
		$customPaginatedArray->add($item);
	endif;
endforeach;

// should return an array of pages that are direct children of the homepage

$total = $customPaginatedArray->count();
$customPaginatedArray->setStart(0);
$customPaginatedArray->setLimit(10);
$customPaginatedArray->setTotal($total);

foreach ($customPaginatedArray as $c) :
	echo $c->title . '<br>';
endforeach;

$pager->render($customPaginatedArray);

 

Link to comment
Share on other sites

$items = $pages->find("id>1");
$home = $pages->get("id=1");

$customPaginatedArray = new PaginatedArray;
foreach ($items as $item) :
    if ($item->parent == $home) :
        $customPaginatedArray->add($item);
    endif;
endforeach;

// should return an array of pages that are direct children of the homepage

$limit = 10;
$start = ($input->pageNum-1)*$limit;
$total = $customPaginatedArray->count();

foreach ($customPaginatedArray->filter("limit=$limit, start=$start") as $c) :
    echo $c->title . '<br>';
endforeach;

$customPaginatedArray->setStart($start);
$customPaginatedArray->setLimit($limit);
$customPaginatedArray->setTotal($total);

echo $customPaginatedArray->renderPager();

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

I can confirm that @matjazp's example works. The thing is though that this still means that you are loading all pages into memory and then paginating. This doesn't seem like a good idea in general - is there a reason you can't limit the find() to the results you want and just use my example which only loads the required pages for each page/view - much more efficient and scalable.

What is the actual set of pages you are trying to query? Have you tried to build a selector that can get what you want with one find operation?

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By fedeb
      Hi,
      I am trying to style the pager navigation bar based on a simple example I found on bootstrap:
      <nav aria-label="..."> <ul class="pagination"> <li class="page-item disabled"> <a class="page-link" href="#" tabindex="-1" aria-disabled="true">Previous</a> </li> <li class="page-item"><a class="page-link" href="#">1</a></li> <li class="page-item active" aria-current="page"> <a class="page-link" href="#">2</a> </li> <li class="page-item"><a class="page-link" href="#">3</a></li> <li class="page-item"> <a class="page-link" href="#">Next</a> </li> </ul> </nav> The code I am using is the following:
      <?php echo $entries->renderPager(array( 'nextItemLabel' => "Next", 'previousItemLabel' => "Prev", 'listMarkup' => "<ul class='pagination'>{out}</ul>", 'itemMarkup' => "<li class='page-item'>{out}</li>", 'linkMarkup' => "<a class='page-link' href='{url}'>{out}</a>", 'currentItemClass' => "page-item active", )); ?> which renders this result: the current page is not styled!

      If I run the original bootstrap example everything works fine, but not through the renderPager options. The problem seems trivial but since I am new to ProcessWire (also to web design) I cannot find it! My main reference is this one.
      Thanks in advance!
       
    • By fruid
      I'm having and always have a hard time building PaginatedArrays, I never know where to put the "limit=24" selector so please enlighten me.
      Here's what I'm doing…
      $categories = $page->protable('start=0, limit=999999'); // this I need in order to retrieve the pages's "categories" and I don't know how to make use of $rows instead for that purpose because of this confusing limit-API $rows = $page->protable; // put ("limit=20") here? $custom = buildSelector($input, $rows); // this function returns an array of selectors depending on the user input $items = new PaginatedArray; // or here? // or here? $items->find("limit=20") // or like this? $items("limit=20") // or like this? $items = $items("limit=20") // or like this? $items = $items->find("limit=20") foreach ($rows as $r) : if ($custom->get('selector')->matches($r)) : $items->add($r); endif; endforeach; // or at this point? and then
      if ($items) { // or maybe somewhere here?     echo '<span class="grey">'.$items->getPaginationString(array(     'label' => 'entries',     'zeroLabel' => '0 entries', // 3.0.127+ only     'usePageNum' => false,     'count' => count($items),     'start' => $items->getStart(),     'limit' => count($items),     'total' => $items->getTotal()     )); and then of course…
      $pager = $modules->get("MarkupPagerNav"); echo '<div class="uk-flex uk-flex-center">'.$pager->render($items, $options).'</div>'; I'm out of ideas and confused cause it doesn't make sense to me either way.
      ____
      The buildSelector function above returns and array…
      $selected = new Selectors("$letter, $searchterm, $category"); $custom = new Wirearray; $custom->set('selector', $selected); $built->set('sort', $sort); return $custom; and each of the new selectors are basically strings ("category=whatever")
      Also, you cannot put the "sort=title" or whatever as a selector for the Selectors function (see above). Why, I know not.
      I don't know if that is the proper way but selecting kind of works now as opposed to many other ways I tried. Selectors always require a lot of trial and error, it seems to have a very sensitive API, always depends on double quotes, single quotes and how you concatenate.
      Thanks for help!
    • By picarica
      Hello si have this gallery, pretty good website, but yesterday client uploaded over 3000 images oto the site, and it cannot handle filtering them out and showing them at the same time , i wanted some simple pagination maybe infinite scrool or onclikc load whatever, but i cannot seem to implement infinite ajax scrool and any other JS methods, nut sure why i still got stuck at the next method, like there is not next page.
      so i wanted to implement PW method of paginating i wanted to use MarkupPagerNav
      so far i have  this code for outputting images
      $pa = $pages->find("template=basic-page|art_gallery, images.tags!=''"); /* $pa = $pages->find("has_parent!=2,id!=2|7,status<".Page::statusTrash.",include=all"); */ echo "<div class='js-filter' id='gal' >"; /* row gtr-50 gtr-uniform */ $frame = $pages->get('/settings/')->watermark; foreach ($pa as $p) { foreach($p->images as $image) { if(!$image->hasTag("act")) { $options = array('quality' => 80, 'upscaling' => true, 'cropping' => 'north', 'sharpening'=>'medium'); $large = $image->size(1200, 0, $options); $wmImage = $large->pim2Load('wm1', ['quality'=>80, 'upscaling' => true, 'sharpening'=>'medium', 'defaultGamma'=>-1])->watermarkLogo($frame, $position='se',$padding=1.5)->pimSave(); /* zmazanie variacii, treba odpoznakovat ked sa menia nastavenie vyssie */ /* $image->pim2Load('wm1')->removePimVariations(); */ $thumb = $image->size(400, 300, $options); echo "<div class='$image->tags grid-item' style=''>"; echo "<span style='overflow:hidden;'class='image fit'>"; echo "<a class='hvr-reveal' href='$wmImage->url'>"; echo "<img uk-scrollspy='cls: uk-animation-fade; repeat: false' src='$thumb->url' alt='$image->tags'>"; echo "</a>"; echo "</span>"; echo "</div>"; } else { $options = array('quality' => 80, 'upscaling' => true, 'cropping' => 'north', 'sharpening'=>'medium'); $large = $image->size(1200, 0, $options); $wmImage = $large->pim2Load('wm2', ['quality'=>80, 'upscaling' => true, 'sharpening'=>'medium', 'defaultGamma'=>-1])->pixelate(25)->smooth(255)->watermarkLogo($frame, $position='se',$padding=1.5)->pimSave(); /* zmazanie variacii, treba odpoznakovat ked sa menia nastavenie vyssie */ /* $image->pim2Load('wm2')->removePimVariations(); */ $thumb = $image->size(400, 300, $options); echo "<div class='$image->tags blur grid-item' style=''>"; echo "<span style='overflow:hidden;'class='image fit'>"; echo "<a class='hvr-reveal' href='$wmImage->url'>"; echo "<img uk-scrollspy='cls: uk-animation-fade; repeat: false' src='$thumb->url' alt='$image->tags'><span>18+</span>"; /* <span>BY OPENING THIS IMAGE YOU CONSET THAT YOU'RE 18 YEARS OR OLDER</span> text copyraightova,y dat vedla obrazky potom */ echo "</a>"; echo "</span>"; echo "</div>"; } } }; to put it  simply, it first searches for sites, and then outputs all images from those sites, pretty simple, it also uses watermarking and uikit filtering
      i have filtering done like this
      $num = 1; echo "<ul class='uk-subnav uk-subnav-pill'>"; foreach(array_unique($alltags) as $key => $tag) { echo"<li uk-filter-control='filter: .$tag;group: $num' class='butt$num' uk-toggle='target: .butt$num ; animation: uk-animation-fade; queued: true'><a href='#'>$tag</a></li>"; echo"<li uk-filter-control='group: $num' class='butt$num active' aria-hidden='true' hidden='' uk-toggle='target: .butt$num; animation: uk-animation-fade'><a href='#'>remove - $tag</a></li>"; $num++; } echo "</ul>"; simple, but i have NO idea how to implement pagination, just because it seems to work that it like find all images, and stores with limit, and then just paginates them, but i cannot apply this method in my code.
      any idea how to make any JS inifite scroll work ? or just how to make this work ? with my setup, or with some modifications, it just have to work as is now
    • By creativejay
      I will preface this by saying I have checked (multiple times) per template (both parent and child, to be totally sure) that they are set to allow pagination.
      What's happening is that my first page of results keeps displaying, despite /page2/ being in the URL. The pagination markup also indicates I am still on page one. This is happening across multiple types of paginated pages.
      $pagination = $pager->render($results, $poptions); The options are just markup...
      $poptions = array( 'numPageLinks' => 5, 'listClass' => 'uk-pagination', 'linkMarkup' => "<a href='{url}'>{out}</a>", 'currentItemClass' => 'uk-active', 'separatorItemLabel' => '<span>&hellip;</span>', 'separatorItemClass' => 'uk-disabled', 'currentLinkMarkup' => "<span>{out}</span>", 'nextItemLabel' => '<i class="uk-icon-angle-double-right"></i>', 'previousItemLabel' => '<i class="uk-icon-angle-double-left"></i>', 'nextItemClass' => '', // blank out classes irrelevant to Uikit 'previousItemClass' => '', 'lastItemClass' => '', ); In the header, I call for the module and the options include:
      $pager = $modules->get('MarkupPagerNav'); include_once("pagination.inc"); Aside from the usual "check that you allowed pagination" advice, what issue might these symptoms indicate?
    • By ottogal
      Hello all,
      using PW 3.0.148 with the regular site profile for a blog, I got an an empty pagination output when I had a Toggle field in the selector.
      The Toggle Fieldtype was introduced with https://processwire.com/blog/posts/pw-3.0.139/ .
      The selector resulting in empty pagination:
      $posts = $pages->find("parent=blog, sort=-date, limit=10, toggle_field=0"); It worked well, when I replaced the Toggle field with a Checkbox field:
      $posts = $pages->find("parent=blog, sort=-date, limit=10, checkbox_field=0"); So the prerequisites for the pagination to work are given.
      The settings for the Toggle field were:
      Formatted value: Integer Label Type: Yes/No Input Type: Toggle buttons Default selected option: No Thanks for any hints!
×
×
  • Create New...