Problem/Motivation
When a Quick Tabs instance (non-AJAX) has two or more Views tabs whose displays use a pager on the same pager element (the Views default, 0), every tab renders the pager of whichever tab's view executed last.
- If the last tab is empty or fits on one page, no tab shows a pager at all.
- Otherwise every tab's pager shows the last tab's page count, so page links and "Next" are wrong for the other tabs.
This started with the change in #3238148. ViewContent::doRender() now calls $view->preExecute() / $view->execute() to check whether the tab is empty, then passes the same, already-executed view to $view->buildRenderable(). When the render element is processed, ViewExecutable::execute() returns early because the view has already run, so the pager's count query and updatePageInfo() don't run again. The core pager element is therefore not re-created for that view before its pager is themed. By then all tabs have executed, and the pager manager holds the last tab's pager. PagerPreprocess::preprocessPager() then returns early when that pager has one page or fewer.
Steps to reproduce
- Create a view of content with two block displays, both using a full pager (5 items per page, pager ID 0). Filter the first to return 20+ results and the second to return none.
- Create a Quick Tabs instance (AJAX off) with a Views tab for each display, the empty one last.
- Place the Quick Tabs block and view the page.
- Expected: the first tab shows a pager with 4+ pages. Actual: no pager is rendered.
Proposed resolution
Build the renderable from a fresh view instance rather than the one already executed for the emptiness check, so the view runs at render time and creates its own pager before that pager is themed (as in 4.1.x):
else {
$view = Views::getView($options['vid']);
if ($source_request) {
$view->setRequest($source_request);
}
$render = $view->buildRenderable($options['display'], $args);
A tab with results then runs its view twice, which comment #23 on #3238148 notes already happens. Giving each display its own pager ID also works around it, but that changes the query string for every tab, and site builders shouldn't have to.
Remaining tasks
- Review MR.
- Add a kernel/functional test covering two paged Views tabs sharing a pager element.
User interface changes
None.
API changes
None.
Data model changes
None.
Issue fork quicktabs-3630358
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #3
davewilly commentedComment #4
joelpittetThanks @davewilly for reporting the bug. I am setting to needs work because the solution feels incorrect and a test would really help sell this problem. I have seen problems with pagers on the same page before, so I know they can be painful to manage.
Also you can use
BlockContent+Viewsblock to do similar tabs, I wonder if this problem exists in that config too.