Comment détecter et modifier les appels AJAX dans Drupal avec un Event Subscriber ?
J’ai eu besoin de détecter les appels ajax dans une vue pour effectuer une commande qui permettait de masquer des éléments. On peut l'utiliser pour mettre à jour le DOM, ajouter des animations, etc. Je vous explique donc comment j’ai géré ce cas avec des Event Subscribers et Commande Interfaces.
Définition Event Subscriber
Un Event Subscriber écoute et réagit à des événements spécifiques déclenchés par le système ou d'autres composants. Il est largement utilisé pour personnaliser ou étendre le comportement d'une application sans modifier directement son code source.
Code complet
<?php
namespace Drupal\ads_content\EventSubscriber;
use Drupal\views\Ajax\ViewAjaxResponse;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Drupal\ads_content\Ajax\AfterViewsAjaxCommand;
/**
* Alter a Views Ajax Response.
*/
class ViewsAjaxResponseSubscriber implements EventSubscriberInterface {
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents() {
$events[KernelEvents::RESPONSE][] = ['onResponse'];
return $events;
}
/**
* Check Ajax response from a view.
*
* @param \Symfony\Component\HttpKernel\Event\FilterResponseEvent $event
* The event process.
*/
public function onResponse(ResponseEvent $event) {
$response = $event->getResponse();
if ($response instanceof ViewAjaxResponse) {
$view = $response->getView();
if ($view->storage->id() === 'search_publications' || $view->storage->id() === 'search_ressources') {
$response->addCommand(new AfterViewsAjaxCommand());
}
}
}
}
Explication détaillée du code
Nous avons d’abord les Namespace et Utilisation des Classes.
namespace Drupal\ads_content\EventSubscriber;
use Drupal\views\Ajax\ViewAjaxResponse;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Drupal\ads_content\Ajax\AfterViewsAjaxCommand;
- Namespace : La classe est définie dans le module
ads_content
, sous le répertoireEventSubscriber
. - Imports :
ViewAjaxResponse
: Représente une réponse AJAX spécifique générée par une vue dans Drupal.EventSubscriberInterface
: Interface à implémenter pour déclarer un Event Subscriber.ResponseEvent
: Événement déclenché lorsque le kernel HTTP génère une réponse.KernelEvents
: Ensemble d'événements liés au cycle de vie de la requête.AfterViewsAjaxCommand
: Commande AJAX personnalisée ajoutée à la réponse.
Enregistrement de l'Event Subscriber
public static function getSubscribedEvents() {
$events[KernelEvents::RESPONSE][] = ['onResponse'];
return $events;
}
getSubscribedEvents
: Méthode qui enregistre les événements auxquels le Subscriber réagit.KernelEvents::RESPONSE
: L'événement est déclenché lorsque le système génère une réponse HTTP.onResponse
: Méthode appelée lorsque l'événement est intercepté.
Vérification de la Réponse AJAX
public function onResponse(ResponseEvent $event) {
$response = $event->getResponse();
if ($response instanceof ViewAjaxResponse) {
$view = $response->getView();
if ($view->storage->id() === 'search_publications' || $view->storage->id() === 'search_ressources') {
$response->addCommand(new AfterViewsAjaxCommand());
}
}
}
Étapes de traitement :
- Récupération de la réponse :
getResponse()
: Permet d'accéder à la réponse HTTP générée.- La méthode vérifie si la réponse est une instance de
ViewAjaxResponse
. Cela signifie qu'il s'agit d'une réponse AJAX d'une vue.
- Identification des vues cibles :
getView()
: Récupère l'objet de la vue à l'origine de la réponse.storage->id()
: Récupère l'ID de la vue pour identifier si elle correspond à une vue ciblée (search_publications
ousearch_ressources
).
- Ajout d'une commande AJAX personnalisée :
addCommand(new AfterViewsAjaxCommand())
: Ajoute une commande AJAX personnalisée à la réponse.AfterViewsAjaxCommand
doit être une classe définie dans votre module (probablement pour exécuter une logique ou modifier le DOM côté client après le traitement AJAX).
Résumé du Fonctionnement
- Le Subscriber s'enregistre pour écouter l'événement
KernelEvents::RESPONSE
. - Lorsqu'une réponse est générée, il vérifie si elle est de type
ViewAjaxResponse
. - Si c'est le cas, il identifie les vues concernées (
search_publications
ousearch_ressources
). - Une commande AJAX personnalisée (
AfterViewsAjaxCommand
) est ajoutée à la réponse, permettant une action spécifique côté client après le chargement des résultats AJAX.
Exemple de commande Ajax
La classe AfterViewsAjaxCommand est une commande AJAX personnalisée dans Drupal. Une commande AJAX est utilisée pour envoyer des instructions spécifiques au client (navigateur) après une requête AJAX. Dans ce cas, la commande ajoute une instruction JavaScript définissant une action personnalisée à exécuter après le rendu d'une vue en AJAX.
<?php
namespace Drupal\ads_content\Ajax;
use Drupal\Core\Ajax\CommandInterface;
/**
* Custom after Ajax Command.
*/
class AfterViewsAjaxCommand implements CommandInterface {
/**
* {@inheritdoc}
*/
public function render() {
return [
'command' => 'afterViewsAjaxCall',
];
}
}
Intégration du JavaScript
Ce code définit un comportement Drupal (Drupal behavior) pour gérer une commande AJAX personnalisée appelée afterViewsAjaxCall
. Voici les points clés :
- Structure d'attache :
Le comportement est attaché aux éléments ayant la classe.js-ads-search-views
via la méthodeonce()
, garantissant que le comportement est exécuté une seule fois par élément. - Fonctionnalité personnalisée :
Une fonctiontoggleNodeListVisibility()
est définie pour effectuer une action spécifique (à compléter selon vos besoins). - Commande AJAX :
La commande personnaliséeafterViewsAjaxCall
est définie dansDrupal.AjaxCommands.prototype
. Elle exécutetoggleNodeListVisibility()
chaque fois que cette commande est reçue d'une réponse AJAX.
(function (Drupal, once) {
Drupal.behaviors.AfterViewsAjax = {
attach: function (context, settings) {
once('js-ads-search-views', '.js-ads-search-views', context).forEach(function (element) {
function toggleNodeListVisibility() {
// custom js
}
Drupal.AjaxCommands.prototype.afterViewsAjaxCall = function (ajax, response) {
toggleNodeListVisibility();
};
});
},
};
})(Drupal, once);
Ajouter un commentaire