Drupal 8/9: Facets AJAX commands

Faceted search

Possible solutions

I came up with three possible solutions:

  • Disable AJAX on the faceted search 💩
  • Listen to the facets_filter JavaScript event 😐
  • Alter the response object of the facet AJAX callback 👍

The JavaScript event

Implementing this solution would be pretty straight forward:

  • Add a JavaScript file
  • Add an event listener
  • Execute (jQuery) AJAX call(s) to the Drupal back-end
  • Update the content with for example jQuery(‘.selector’).html(response);

Altering the response object

After some researching I figured out that all facet AJAX requests were routed through one specific path:

/facets-block-ajax
  1. I didn’t need an extra (unnecessary) request to the back-end
  2. I only had to add some PHP code to make this work. Everything simple and centralized, just as I like my code to be.

The best way forward

To me, it was clear that the “Alter the response object of the facet AJAX callback” was by far the best approach. Now I just had to implement it… 💻

Overriding the facet route

I just registered a route subscriber in my services.yml file and added the subscriber:

Adding a custom controller

This controller extends the base FacetBlockAjaxController class which does all the heavy lifting. The only thing I added was an event dispatcher which dispatches a custom event to alter the response object. This allowed me to alter the AJAX commands attached to the response.

Defining a custom event

The next step was to define the custom FacetsAlterAjaxCommandsEvent event class. This class keeps track of the altered response object throughout the entire event subscriber process:

Adding event subscribers

At this point, my “mini framework” was ready to be put to work. I added several custom modules which all had an event subscriber:

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store