Multiple Views with auto loading pager on a single page with tabs

Created on 5 August 2023, over 1 year ago
Updated 25 April 2024, 8 months ago

Problem/Motivation

I've observed an interesting combination of issues when placing multiple views on a single page and enabling the infinite scroll with the autoload for all of them. This setup makes sense if we put the views in separate toggleable containers (eg. tabs, accordions, etc).

1. display:none

Since most of the togglable elements will be implemented with the property "display" set to "none" (display: none) when in collapsed/hidden state, the first issue will manifest when a view loads in one of the hidden containers. In this case, the vertical offset of the pager [ $pager.offset().top ] will hold the value of 0 (zero), and the condition within the isLoadNeeded function will be evaluated as true. This means it will keep on loading the next page in the view until it reaches the end. Basically, we will see a throbber appearing multiple times as soon as our page loads. Once it stops, we can toggle our container (tab) so it displays the view, and we will see all the whole result set loaded. (It may be similar to the issue described here - https://www.drupal.org/project/views_infinite_scroll/issues/3207098 🐛 Immediate loading of more results without user scrolling (patch included) Postponed: needs info )

2. Only the first view can be autoloaded

After resolving the first issue, I encountered another one. With multiple views being on the same page, the first interaction with one of the views (loading the next result set), will remove the event binding [ $window.off(scrollEvent);] for all of the views. The assumption is that the js behavior will run post-AJAX response, and we will re-bind the event handler again to the view. And this logic works fine with a single view, but not multiple - running the once() with the new context will associate the event handler only with a single pager, not all of them. Therefore the other view(s) will no longer be bound to the scrollEvent, hence making them unresponsible.

Steps to reproduce

1. Place multiple views (with infinite scroll & autoload enabled) on a single page inside togglable containers, such as UI Tabs ( https://www.drupal.org/project/jquery_ui_tabs ). However, any container with the display property set to "none" will do.

2. When the page loads, the autoloader will start making AJAX calls to pull the next set of results into the view until it reaches the end of the result set.

3. If updating the test function

var isLoadNeeded = function () {
      return window.innerHeight + window.pageYOffset > $pager.offset().top - scrollThreshold;
  };

to

var isLoadNeeded = function () {
     if ($pager.offset().top) {
        return window.innerHeight + window.pageYOffset > $pager.offset().top - scrollThreshold;
     }
     else {
        return false;
     }
  };

solvers our first issue, the second one can be replicated by toggling to different tabs/containers and scrolling down to trigger the autoload.

4. You will notice that only the first (any) view that starts autoloading will continue to do so. The rest will become unresponsive.

Proposed resolution

1. Adjust the condition for checking isLoadNeeded to make sure that the vertical offset for the pager is not zero
https://git.drupalcode.org/project/views_infinite_scroll/-/blob/2.0.x/js...

2. Keep track of the number of active views and re-bind the scrollEvent outside of the once() callback chain. I will provide my solution as a forked branch.

Similar Issues

Based on my search of the issue queue, I found similar issues, which may or may not be resolved by the proposed solution:

https://www.drupal.org/project/views_infinite_scroll/issues/3207098 🐛 Immediate loading of more results without user scrolling (patch included) Postponed: needs info
https://www.drupal.org/project/views_infinite_scroll/issues/2877652 🐛 infinite scroll does not work for multiple views on a single page Needs work

🐛 Bug report
Status

Needs review

Version

2.0

Component

Code

Created by

🇺🇸United States dan.d

Live updates comments and jobs are added and updated live.
  • Needs tests

    The change is currently missing an automated test that fails when run with the original code, and succeeds when the bug has been fixed.

Sign in to follow issues

Comments & Activities

  • Issue created by @dan.d
  • Status changed to Needs work over 1 year ago
  • 🇩🇪Germany Anybody Porta Westfalica

    Hi @dan.d thanks for reporting the issue and filling the issue summary that details. Really good job! Could you prepare a MR to review?
    At least, if it wasn't or can't be solved in one of the other issues. Thank you very much.

  • Open in Jenkins → Open on Drupal.org →
    Core: 10.0.7 + Environment: PHP 8.2 & MySQL 8
    last update over 1 year ago
    2 pass
  • @dand opened merge request.
  • Status changed to Needs review over 1 year ago
  • 🇺🇸United States dan.d

    Julian (@Anybody), I've created an MR and switched the status of the issue to "Needs review." I'm also attaching the screencap of my test with tabs.

  • Open on Drupal.org →
    Core: 10.0.7 + Environment: PHP 8.2 & MySQL 8
    last update over 1 year ago
    Not currently mergeable.
  • @anybody opened merge request.
  • 🇩🇪Germany Anybody Porta Westfalica

    Thank you very much @dan.d! Great work!

    I'll take a look asap, but to be sure it's working under all the different conditions, we need test coverage for this module. It broke too often in the past. See 📌 Write tests, tests, tests Active

    Would be super nice, if you and other users could help to push things forward over there. Alternatively, you could add a test in this issue for the functionality, but please understand that any change is dangerous without them. There are so many different conditions, under which this module is used.

  • 🇮🇳India bablukmt

    I'm also facing the same issue, Is any patch available for this?

Production build 0.71.5 2024