Jump to content

pagination never works


froot
 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

    //$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

@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 2
  • Thanks 2
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

×
×
  • Create New...