Sometimes developing complex forms with AJAX there is a necessity to force triggering Drupal behaviors. Drupal.attachBehaviors() is used to be called after AJAX call but sometimes in specific cases it doesn't work. For such cases there is a solution – creation of custom AJAX command.
First thin you need to do is to create a PHP class for new AJAX command in Drupal\my_module\Ajax namespace:
<?php
namespace Drupal\my_module\Ajax;
use Drupal\Core\Ajax\CommandInterface;
/**
* An AJAX command to trigger Drupal.attachBehaviors().
*/
class TriggerAttachBehaviors implements CommandInterface {
/**
* {@inheritdoc}
*/
public function render() {
return [
'command' => 'triggerAttachBehaviors',
];
}
}
Then you need to create js file in your module folder e.g.: assets/js/attach-behaviors-command.js:
(function (Drupal) {
/**
* Ajax command for trigger Drupal.attachBehaviors().
*/
Drupal.AjaxCommands.prototype.triggerAttachBehaviors = function (ajax, response, status) {
Drupal.attachBehaviors();
};
})(Drupal);
Javascript file has to be added to some library to be added to the page, like
my_module.custom_js:
js:
assets/js/attach-behaviors-command.js: { }
dependencies:
- core/drupal
- core/drupal.ajax
Feel free to attach this library any way you know. After that it will be possible to use that custom AJAX command inside AJAX callbacks the following way:
/**
* {@inheritdoc}
*/
public function ajaxFormCallback(array &$form, FormStateInterface $form_state, $reset_secondary = FALSE) {
$response = parent::ajaxFormCallback($form, $form_state, $reset_secondary);
// Any needed logic.
// Triggering behaviors.
$response->addCommand(new TriggerAttachBehaviors());
// The rest of the logic.
return $response;
}
That's it!