Skip to content

Progressively enhanced filters and search

Lukas Bestle edited this page May 2, 2023 · 2 revisions

The default block snippet uses a simple HTML form for the frontend search and filters.

For a more robust and accessible experience, I strongly recommend to keep the HTML form. However it is possible to progressively enhance it with instant filters and search using JavaScript.

The Downloads Block plugin already comes with a JSON API route for this purpose. You can access the URL of this route with $block->apiEndpoint() inside a custom block snippet. E.g. set this URL on a data-api attribute of the form so you can access it in the frontend.

The exact frontend implementation varies based on your block snippet. The general approach is to add an event listener for changes to any of the form fields. Once the visitor changes the filters or enters a search term, serialize the form data and send it to the API route with a GET request. In return you will get a JSON array with all downloads that match the query as well as pagination data:

{
  "results": {
    "downloads/product1_brochure_de.pdf": {
      "filename": "product1_brochure_de.pdf",
      "title": "Product 1 Brochure DE",
      "size": 7441,
      "niceSize": "7.27 KB",
      "url": "https://example.com/media/pages/downloads/abcdefghij-1234567890/product1_brochure_de.pdf"
    },
    "downloads/product1_datasheet_de.pdf": {
      "filename": "product1_datasheet_de.pdf",
      "title": "Product 1 Data sheet DE",
      "size": 7441,
      "niceSize": "7.27 KB",
      "url": "https://example.com/media/pages/downloads/abcdefghij-1234567890/product1_datasheet_de.pdf"
    },
    "downloads/product1_instructions_de.pdf": {
      "filename": "product1_instructions_de.pdf",
      "title": "Product 1 Instructions DE",
      "size": 7441,
      "niceSize": "7.27 KB",
      "url": "https://example.com/media/pages/downloads/abcdefghij-1234567890/product1_instructions_de.pdf"
    }
  },
  "pagination": {
    "page": 1,
    "firstPage": 1,
    "lastPage": 1,
    "pages": 1,
    "offset": 0,
    "limit": 15,
    "total": 3,
    "start": 1,
    "end": 3
  }
}

To ensure good performance, it is recommended to debounce events of the search field so the API route is not called for every entered character.

You can paginate the results by appending a &page=x query param to the API route.

Clone this wiki locally