Clicky

Ajax API. Creating a custom Ajax command in Drupal 8

Drupal 7 first introduced the Ajax API, which is quite handy and was also able to expand by writing its custom Ajax functions. In Drupal 8, the Ajax API has become more informative and even more flexible.

AJAX, Ajax (Asynchronous JavaScript and XML) - an approach to building interactive user interfaces for Web applications, which consists in the "background" exchange of browser data with a web server. As a result, when you update the data, the web page does not completely restart, and web applications become faster and more convenient.
AJAX – is not an independent technology, but it is the concept of using several related technologies. With the correct implementation AJAX allow in reduce the load on the server in several times.

Creating of Ajax link

First we'll create a simple Ajax link that will return alert () with the passed parameter. Creating Ajax links can be broken down into 2 main stages:

• Creating a Controller;

• Definition of Ajax Commands.

As always, we will create a custom module, call it custom_ajax_link:

Custom_ajax_link.info.yml - file

 
         name: 'Custom Ajax Link'
         
         description: 'A simple implementation of Ajax links'
         
         core: 8.x
         
         type: module
         
         package: 'Other'
         
         version: '8.x-1.0'
         

Custom_ajax_link.routing.yml - routing file

 
        custom_ajax_link.routing:
          
          path: '/custom_ajax_link /{name}'
         
         defaults:
           
           _title: 'Custom Ajax Link'
          
          _controller: '\Drupal\custom_ajax_link \Controller 
          
          \CustomAjaxLinkController :: customAjaxLinkAlert'
         
         requirements:
         
         _permission: 'access content'
        

As you can see in the routing file, in the parameter path we passed, in addition to the URL, another parameter {name}. This parameter will be available in the controller, as a variable, with the name of this parameter, in this case $name.

CustomAjaxLinkController.php - the controller file

 
        <? php

        namespace Drupal\custom_ajax_link\Controller;

        use Drupal \Core\Ajax\AjaxResponse;
        use Drupal \Core\Ajax\AlertCommand;
        use Drupal \Core\Controller\ControllerBase;

        class CustomAjaxLinkController extends ControllerBase {

          public function customAjaxLinkAlert ($name) {

            # New responses
            $ response = new AjaxResponse ();

            # Commands Ajax
            $ response-> addCommand (new AlertCommand ('Hello'. $name));

            # Return response
            return $response;

          }

        }
        

I want to note that if you pass an additional parameter to the controller from the routing file, do`nt forget to also define it in the method of the controller class. As you can see for working with Ajax, we use 2 additional libraries:

  • AjaxResponse - the main Ajax API class, returns an object in the JSON format for Ajax requests;

  • AlertCommand - the Ajax API command, displays a warning window - alert ();

Next, activate the module, but you naturally will not happen. Now we need to create the link itself, by clicking on which we will receive a response from Ajax. We create an ordinary article with a link of the form:

<a class="use-ajax" href="/custom_ajax_link/Pantey"> open alert for ajax link testing </a>

I want to note that the CSS class - use-ajax for the link - is mandatory, with this class we make it clear to Drupal that for this reference it is necessary to apply the Ajax request.

Now we look, that at us it has turned out:

Testing Ajax link
Open alert for ajax link testing

As you can see everything works, but there is still some special feature (by the way it was present in Drupal 7) - in this case it will work only for the administrator, for the anonymous user Ajax will not work, it is due to the fact that for the administrator automatically the library drupal.ajax is connected, due to the use of the admin part of the site, but for the anonym, by default, there is no need for this library, so we are correcting this matter.

Create a file in the root of the module - custom_ajax_link.module

 
        <php

        / **
         * @param $ variables
         * Implements hook_preprocess_page ()
         * /
        function custom_ajax_link_preprocess_page (& $ variables) {

          $ logged_in = \ Drupal :: currentUser () -> isAuthenticated ();
          if (! $ logged_in) {
            # Add libraries for anonymous
            $ libraries ['# attached'] ['library'] [] = 'core / drupal.ajax';
            render ($ libraries);
          }

        }
        

Next, we clean the site's cache and see the result under the anonym.

Open alert for ajax link testing

JQuery Ajax API commands in Drupal 8

Now we can start acquaintance with JQuery commands.

JQuery list of Ajax API commands - Drupal 8

        • AlertCommand ()
        • AddCssCommand ()
        • BeforeCommand ()
        • AppendCommand ()
        • AfterCommand ()
        • ChangedCommand ()
        • InsertCommand ()
        • InvokeCommand ()
        • HtmlCommand ()
        • CssCommand ()
        • DataCommand ()
        • ReplaceCommand ()
        • RestripeCommand ()
        • RemoveCommand ()
        • PrependCommand ()
        • RedirectCommand ()
        

AlertCommand ($text) - displays a warning window, an analog alert () on JavaScript.
Where:
• $text - Message text

class - \Drupal\Core\Ajax\AlertCommand;

AddCssCommand ($style) - Adds the necessary inline styles to the <head> </ head>.
Where:
• $style - CSS styles

class - \Drupal\Corе \Ajax\AddCssCommand;

BeforeCommand ($selector, $html, $settings = NULL) - the analogue before () on Jquery, adds the content before the specified selector.
Where:
• $selector - the selector before which you need to insert the content
• $html-content to insert
• $settings - advanced settings

class - \Drupal\Core\Ajax\BeforeCommand;

AppendCommand ($selector, $html, $settings = NULL) - an analog of append () on Jquery, adds the content after all the elements inside the selected selector.
Where:
• $selector - the element selector, after which you need to insert the contents
• $html-content to insert
• $settings - advanced settings

class - \Drupal\Core\Ajax\AppendCommand;

AfterCommand ($selector, $html, $settings = NULL) - is an analog of the after () method on Jquery, adds the content after the specified element.
Where:
• $selector - an element selector, after which you need to insert the content
• $html-content to insert
• $settings - advanced settings

class - \Drupal \Core\Ajax\AfterCommand;

ChangedCommand ($selector, $asterisk = NULL) - adds a marker to the elements that were changed after using Ajax, by adding a CSS class - ajax-changed.
Where:
• $selector - the selector to which the CSS class will be added - ajax-changed
• $asterisk - selector, for which you need to display the asterisk in the form of an asterisk "*"

class - \Drupal\Core\Ajax\ChangedCommand;

InsertCommand ($selector, $data, $settings)- replaces the specified selector with the contents.
Where:
• $selector - the selector to be replaced
• $data - content to change
• $settings - advanced settings

class - \Drupal\Core\Ajax\InsertCommand;

InvokeCommand ($selector, $method, $arguments) - Used to call an arbitrary Jquery method.
Where:
• $selector - selector for which you want to apply the Jquery method
• $method - the Jquery method
• $arguments - the method's properties (argument)

class - \Drupal\Core\Ajax\InvokeCommand;

DataCommand ($selector, $name, $value) - an analog of the data () method on Jquery, adds / changes the value of the data attribute for the specified selector.
Where:
• $selector - the selector for which you want to change the date attribute;
• $name - data attribute name;
• $value - the data value of the attribute

class - \Drupal\Core\Ajax\DataCommand;

CssCommand ($selector, $css) - adds inline styles for the selected selector.
Where:
• $selector - selector for which you want to apply inline styles
• $css - array, with CSS styles
I want to note that the $css array should contain the name of the style as the key, and as the value its property

class - \Drupal\Core\ Ajax\CssCommand;

HtmlCommand ($selector, $data, $settings) - an analog of the html () method on Jquery, replaces the contents of the selected selector.
Where:
• $selector - the selector whose content is to be replaced;
• $data - content to change;
• $settings - advanced settings

class - \Drupal\Core\Ajax\HtmlCommand;

ReplaceCommand ($selector, $data, $settings) - an analog of the replace () method on Jquery, replaces the selector with the specified content.
Where:
• $selector - the selector to be replaced
• $data - the content to replace
• $settings - advanced settings

class - \Drupal\Core\Ajax\ReplaceCommand;

RestripeCommand ($selector) - the command updates the CSS classes for the odd /even table.
Where:
• $selector - the table selector for which you want to update the classes

class - \Drupal\Core\Ajax\RestripeCommand;

PrependCommand ($selector, $data, $settings) - is an analog of the prepend method on Jquery, inserts the contents inside the specified selector before all the contents.
Where:
• $selector - selector for which you want to insert content
• $data - content to insert
• $settings - advanced settings

class - \Drupal\Core\Ajax\PrependCommand;

RedirectCommand ($url) - Ajax command for a redirect to the specified URL, uses window.location for this.
Where:
• $url - URL for the redirect

class - \Drupal\Core\Ajax\RedirectCommand;

RemoveCommand ($selector) - an analog of the remove () method on Jquery, deletes the elements that correspond to this selector.
Where:
• $selector - selector to delete

class - \Drupal\Core\Ajax\RemoveCommand;

Some examples of Ajax commands:

AppendCommand()
 
        <php
        # Commands Ajax - AppendCommand()
        $selector = '.block';
        $content = 'This new content';
        $response->addCommand(new AppendCommand($selector, $content));
        

CssCommand()
 
        <php
        # Commands Ajax - CssCommand()
        $selector = '.block';
        $css = array(
        'background-color' => '#ff0000',
        'color' => '#fff',
        );
        $response->addCommand(new CssCommand($selector, $css));

Very often you can to deal with the situation when existing Ajax commands are not enough and it is associated, usually with the use of third-party libraries, when the library has its own set of commands and properties.


Creating a custom Ajax command in Drupal 8

Now let's consider how to create your custom Ajax command, naturally the whole process will be implemented in the custom module, in my case it will be called - custom_ajax_command.

The whole process of expanding the list of Ajax commands can be divided into 2 stages:
 • Define the Ajax command (name, variables);
 • Description of the Jquery method for this command.
In our case, a couple more items will be added:
 • Create a library that will contain our Jquery method;
 • Connecting a library to a page.

Create the module - file custom_ajax_info.yml
 
        name: 'Custom Ajax Command'
        
        description: 'A simple implementation of the Ajax custom command'
        
        core: 8.x
        
        type: module
        
        package: 'Other'
        
        version: '8.x-1.0'
        
Define custom Ajax command - the file CustomAjaxCommand.php
 
     <? php

        namespace Drupal \ custom_ajax_command \ Ajax;
        use Drupal \Core\Ajax\CommandInterface;

        class CustomAjaxCommand implements CommandInterface {

          protected $ message;
          # Constructs
          public function __construct ($ message) {
            $ this-> message = $ message;
          }

          # Implements Drupal \Core\Ajax\CommandInterface: render ().
          public function render () {
            return array (
              'command' => 'customAjaxCommand', // Required property - specifies the name of the custom Jquery (JS) method that will be started
              'message' => $ this-> message, // Variables that will be available in response
            );
          }
        }
            

I want to note who forgot, in Drupal 8 the development is built according to the PSR-4 standard, so all the classes should be in the src directory of your module.
We describe the Jquery method, for the custom command - the file custom_ajax_command.js. This file will be located in the js directory of your module.

 
        (function ($, Drupal) {

          if (Drupal.AjaxCommands) {

            // Custom Ajax command
            Drupal.AjaxCommands.prototype.customAjaxCommand = function (ajax, response, status) {
              alert (response.message);
            }

          }

        }) (jQuery, Drupal);
        

Next, create a library that will contain a file describing the Jquery method, our Ajax command.

Custom_ajax_command.libraries.yml file
 
        # Libraries for Custom Ajax command
        custom_ajax_command:
          version: VERSION
          js:
            # Add JS files
            Js/custom_ajax_command.js: {}
          dependencies:
            - core/drupal.ajax
            - core/jquery
            - core/ jquery.once
            - core/ drupal
        

Now we need to connect this library to the pages of our site. I want to note that we connect this library to all pages of the site only as an example, on your sites always connect the library only where it is needed.

File custom_ajax_command.module
 
            <? php

            / **
             * @param $ variables
             * Implements hook_preprocess_page ()
             * /
            function custom_ajax_command_preprocess_page (& $ variables) {

              $variables ['# attached'] ['library'] [] = 'custom_ajax_command / custom_ajax_command';

              # Add libraries for anonymous
              $logged_in = \Drupal :: currentUser () -> isAuthenticated ();
              if (! $ logged_in) {
                $libraries ['# attached'] ['library'] [] = 'core/drupal.ajax';
              }

              render ($libraries);

            }

With the creation of the custom Ajax command, we are done, now you can use it in your controllers

 
            <? php
           
            # Custom Ajax command
            $message = 'This alert () was started from the Ajax custom command';
            $response-> addCommand (new CustomAjaxCommand ($ message));

In this article, we have read about the Ajax API in Drupal 8, learned how to make the Ajax link, read about the variety of Ajax commands, and most importantly we have seen how to create our own custom Ajax command. I wish you good luck in the further study of Drupal 8.

Quick Free Quote
We respect your privacy. NO SPAM No selling your personal data.
We will respond to your query & collect further details within 24 hours. Guaranteed!

Support

We are friendly people who love to talk. So go ahead and contact us.

Technologies

Awards & Certification