AJAX pagination inside the Change Selector doesn't scroll to top of results

Hi,

On my WooCommerce product archive (Shop page and product category archives) I’m using the Cornerstone Forms with AJAX filtering enabled. The pagination is placed inside the container that I’ve defined as the Change Selector.

Live example: https://terraristik-district.de/shop/ - scroll down to the pagination and click “Page 2”.

Problem: When I click a pagination link (e.g. “Page 2”), the AJAX request correctly loads the next page and swaps the content in place (the URL updates via pushState to …&paged=2), but the viewport does not scroll back to the top of the results - it stays exactly where the pagination sits (bottom of the page). As a result, users barely notice that the page changed.

I’ve confirmed it’s an AJAX swap (no full page reload). A custom delegated JS click handler that scrolls to the top did not work reliably - the AJAX/history handling seems to override or interrupt it.

Question: Is there a built-in option to make the AJAX filter/pagination scroll to the top of the results container after a page change? If not, is there a JS event or hook that Cornerstone fires when the AJAX filtering/pagination completes, that I can hook into to trigger the scroll?

Environment: Pro theme (latest), Cornerstone 7.8.8, WooCommerce 10.9.3

Thanks!

Hey @mrdplusd,

1. Is there a built-in option to scroll to the top?

No. There is no built-in UI option, toggle, or dedicated JavaScript event hook fired upon the completion of Cornerstone Forms AJAX filtering/pagination.

2. Why did standard jQuery/JS scroll listeners fail?

Cornerstone Forms performs its AJAX request using the native browser fetch() API rather than jQuery (jQuery.ajax). Because of this, global jQuery events like $(document).ajaxComplete() will never trigger.


How to Hook into it (Requires Custom development)

Please just note that the following suggestion involves custom codes. Custom coding is beyond the scope of our theme support therefore we cannot provide support in case of issues arising from the use our custom suggestion. For this, you can subscribe to our One service where we provide custom coding recommendations.


Since there isn’t a direct callback event, you can use any of the following reliable client-side approaches:

Option A: Use a MutationObserver on the Results Container (Recommended)

Since Cornerstone’s AJAX handler swaps the HTML of the results container (l.outerHTML = u.outerHTML), a MutationObserver can detect this DOM change and trigger the scroll.

document.addEventListener('DOMContentLoaded', function() {
  // Replace with your defined Change Selector container selector
  const targetContainer = document.querySelector('.your-results-container'); 

  if (targetContainer) {
    const observer = new MutationObserver(function(mutations, obs) {
      // Scroll to the top of the container when a DOM replacement happens
      targetContainer.scrollIntoView({ behavior: 'smooth', block: 'start' });
    });

    // Observe the parent container for changes
    if (targetContainer.parentNode) {
      observer.observe(targetContainer.parentNode, { childList: true });
    }
  }
});

Option B: Intercept the Native fetch Request

You can wrap the global window.fetch API to listen for requests that are generated by the Cornerstone filter form:

(function() {
  const originalFetch = window.fetch;
  window.fetch = async function(...args) {
    const response = await originalFetch(...args);
    
    // Check if the request matches a Cornerstone AJAX submission (usually POSTs to the archive url)
    const isCornerstoneAjax = args[1] && args[1].method === 'post' && args[1].body instanceof FormData;
    
    if (isCornerstoneAjax) {
      // Allow the DOM replacement to execute first, then scroll
      setTimeout(() => {
        const targetContainer = document.querySelector('.your-results-container');
        if (targetContainer) {
          targetContainer.scrollIntoView({ behavior: 'smooth', block: 'start' });
        }
      }, 50);
    }
    
    return response;
  };
})();