craft icon indicating copy to clipboard operation
craft copied to clipboard

Add pagination back and forward fix to the filter component.

Open KarelJanVanHaute opened this issue 6 months ago • 0 comments

See KULVAI-438. Add the popstate listener to the initReloadedClicks function.

private initReloadedClicks() {
    document.addEventListener(
      'click',
      (e) => {
        // loop parent nodes from the target to the delegation node
        for (let target = <Element>e.target; target && !target.isSameNode(document); target = target.parentElement) {
          if (target.matches('.js-filter-pagination a')) {
            e.preventDefault();
            const href = (target as HTMLAnchorElement).href;
            if (href != 'javascript:void(0);') {
              this.showLoading();
              this.getFilterData((target as HTMLAnchorElement).href);
            }
            break;
          }
          if (target.matches('.js-clear-filter-element')) {
            e.preventDefault();
            const data = JSON.parse(target.getAttribute('data-filter-elements'));
            this.clearElements(data);
            break;
          }
        }
      },
      false
    );

    window.addEventListener('popstate', (event) => {
      this.showLoading();
      this.getFilterData(window.location.href, false, false);
    });
  }

  private getFilterData(url, clearPage = false, pushState = true) {
    const _self = this;
    if (this.xhr) {
      this.xhr.abort();
    }

    // Scroll to the scrollToElement or loader. To prevent a weird footer show on windows.
    this.scrollToStart();

    // Go back to page 1 when set changes
    if (clearPage) {
      const regexResult = window.location.pathname.match(/([^\?\s]+\/)([p][0-9]{1,3}.?)(.*)/);

      if (regexResult && regexResult[1]) {
        url = regexResult[1] + '?' + this.formElement.serialize();
      }
    }

    this.xhr = new XMLHttpRequest();
    this.xhr.open('GET', url, true);

    this.xhr.onload = function () {
      if (this.status >= 200 && this.status < 400) {
        const responseElement = document.implementation.createHTMLDocument('');
        responseElement.body.innerHTML = this.response;
        const resultsBlock = responseElement.querySelector('.js-filter-results');
        if (resultsBlock) {
          _self.resultsElement.innerHTML = resultsBlock.innerHTML;

          _self.ariaLiveElement.innerHTML = responseElement.querySelector('.js-filter-aria-live').innerHTML;

          if (pushState) {
            history.pushState('', 'New URL: ' + url, url);
          }

          _self.scrollToStart();

          _self.hideLoading();
          _self.styleClear();
        } else {
          console.error('Could not find data on returned page.');
        }
        const extraInfoBlock = responseElement.querySelector('.js-filter-extra-info');
        if (extraInfoBlock) {
          _self.extraInfoElement.innerHTML = extraInfoBlock.innerHTML;
        }
      } else {
        console.error('Something went wrong when fetching data.');
      }
    };

    this.xhr.onerror = function () {
      console.error('There was a connection error.');
    };

    this.xhr.send();
  }

KarelJanVanHaute avatar Aug 09 '24 12:08 KarelJanVanHaute