SlideShare a Scribd company logo
Demystifying Ajax
Callback Commands
(in Drupal 8)
Mike Miles
Genuine ( )wearegenuine.com
All the internet places: mikemiles86
Defining Callback Commands
Instructions built by the Server and 
executed by the Client in an Ajax event.
Callback Command: JavaScript
Attached to 'Drupal.AjaxCommands.prototype'
Defined in 'misc/ajax.js'
Accepts 3 arguments:
ajax
response
status
Wrapper for additional JavaScript
Callback Structure: JavaScript
01 (function ($, window, Drupal, drupalSettings) {
02 'use strict';
03 /**
04 * [commandName description]
05 *
06 * @param {Drupal.Ajax} [ajax]
07 * @param {object} response
08 * @param {number} [status]
09 */
10 Drupal.AjaxCommands.prototype.[commandName] = function(ajax, response, status){
11
12 // Custom javascript goes here ...
13
14 }
15
16 })(jQuery, this, Drupal, drupalSettings);
[module]/js/[javascript].js
Example of the structure for the JavaScript half of a callback command as defined in a module.
Callback Command: PHP
Class that implements CommandInterface
Defines a method called 'render'
Returns an associative array:
Must have element with key of 'command'
Value must be name of JavaScript function
Other elements passed as response data
Callback Structure: PHP
01 namespace Drupal[module]Ajax
02 use DrupalCoreAjaxCommandInterface;
03
04 // An Ajax command for calling [commandName]() JavaScript method.
05 class [CommandName]Command implements CommandInterface {
06
07 // Implements DrupalCoreAjaxCommandInterface:render().
08 public function render() {
09 return array(
10 'command' => '[commandName]', // Name of JavaScript Method.
11 // other response arguments...
12 );
13 }
14 }
[module]/src/Ajax/[CommandName]Command.php
Example of the structure for the PHP half of a callback command as defined in a module.
Core Example: Remove
01 Drupal.AjaxCommands.prototype = {
02 // ...
03 /**
04 * Command to remove a chunk from the page.
05 *
06 * @param {Drupal.Ajax} [ajax]
07 * @param {object} response
08 * @param {string} response.selector
09 * @param {object} [response.settings]
10 * @param {number} [status]
11 */
12 remove: function (ajax, response, status) {
13 var settings = response.settings || ajax.settings || drupalSettings;
14 $(response.selector).each(function () {
15 Drupal.detachBehaviors(this, settings);
16 })
17 .remove();
18 },
19 //...
misc/ajax.js
The JavaScript function for the core 'remove' callback command. It is basically a wrapper for the jQuery
'remove' method.
Core Example: RemoveCommand
01 namespace DrupalCoreAjax;
02 use DrupalCoreAjaxCommandInterface;
03 /**
04 * Ajax command for calling the jQuery remove() method.
05 * ...
06 */
07 class RemoveCommand Implements CommandInterface {
08 // ...
09 /**
10 * Implements DrupalCoreAjaxCommandInterface:render().
11 */
12 public function render() {
13 return array(
14 'command' => 'remove',
15 'selector' => $this->selector,
16 );
17 }
18 }
core/lib/Drupal/Core/Ajax/RemoveCommand.php
The PHP class for the core 'remove' callback command. Implements CommandInterface, so it must
define the method 'render' that returns an associative array.
PHP
01 //...
02 public function render() {
03 return array(
04 'command' => 'remove',
05 'selector' => $this->selector,
06 );
07 }
core/lib/Drupal/Core/Ajax/RemoveCommand.php
JavaScript
01 //...
02 remove: function (ajax, response, status) {
03 var settings = response.settings || ajax.settings || drupalSettings;
04 $(response.selector).each(function () {
05 Drupal.detachBehaviors(this, settings);
06 })
07 .remove();
08 },
misc/ajax.js
Can see how the two halfs are tied together. Value on line #4 of PHP matches JavaScript function name
defined on line #2 in JavaScript. Passed CSS selector on line #5 in PHP is used on line #4 in JavaScript.
Callback Commands
Used in all Ajax requests
Composed of two parts: JavaScript function, PHP Class
Provided by core and modules
Creating Callback Commands
Example Scenario
Create a callback command for the jQuery 'SlideDown' animation
Create a Module
01 name: 'Slide Down Command'
02 type: module
03 description: Provides an Ajax Callback command for the jQuery SlideDown method.
04 package: other
05 core: 8.x
slide_down/slide_down.info.yml
Custom Ajax callback commands must be defined in a module.
Create JavaScript Function
01 (function ($, window, Drupal, drupalSettings) {
02
03 'use strict';
04
05 // Command to Slide Down page elements.
06 Drupal.AjaxCommands.prototype.slideDown = function(ajax, response, status){
07 // Get duration if sent, else use default of slow.
08 var duration = response.duration ? response.duration : "slow";
09 // slide down the selected element(s).
10 $(response.selector).slideDown(duration);
11 }
12 })(jQuery, this, Drupal, drupalSettings);
slide_down/js/slidedown-command.js
Attach a JavaScript function to the AjaxCommands object provided by the Ajax Framework. Accepts the
three arguments and is a wrapper for the jQuery method.
Create Asset Library
01 slidedown:
02 version: VERSION
03 js:
04 js/slidedown-command.js; {}
05 dependencies:
06 - core/drupal.ajax
slide_down/slide_down.libraries.yml
In Drupal 8 custom JavaScript files must be added to an asset library to be able to be included on a
page.
Create PHP Class
01 namespace Drupalslide_downAjax;
02 use DrupalCoreAjaxCommandInterface;
03
04 class SlideDownCommand implements CommandInterface {
05 // ...
06 // Constructs an SlideDownCommand object.
07 public function __construct($selector, $duration = NULL) {
08 $this->selector = $selector;
09 $this->duration = $duration;
10 }
11
12 // Implements DrupalCoreAjaxCommandInterface:render().
13 public function render() {
14 return array(
15 'command' => 'slideDown',
16 'method' => NULL,
17 'selector' => $this->selector,
18 'duration' => $this->duration,
19 );
20 }
21 }
slide_down/src/Ajax/SlideDownCommand.php
Create a PHP class that implements CommandInterface. Must define a 'render' method and return an
associative array. In the array, pass the element with key of 'command' and value being the name of the
JavaScript function and any repsonse data.
To Create a Callback Command:
Create a module
Attach JavaScript function to 'Drupal.AjaxCommands.prototype'
Define an asset library
Create PHP class that implements 'CommandInterface'
Using Callback Commands
Example Scenario
Load watchdog log message details onto the overview page using
Ajax commands.
Add Ajax Library to Page
01 use DrupaldblogControllerDbLogController as ControllerBase;
02
03 class DbLogController extends ControllerBase {
04 // Override overview() method.
05 public function overview() {
06 $build = parent::overview();
07 // ...
08 // Add custom library.
09 $build['#attached']['library'][] = 'ajax_dblog/ajax-dblog';
10 return $build;
11 }
12 // ...
13 }
ajax_dblog/src/Controller/DbLogController.php
Need to attach custom library onto page so that custom JavaScript and Ajax Framework is included.
01 ajax-dblog:
02 version: VERSION
03 css:
04 component:
05 css/ajax_dblog.module.css: {}
06 js:
07 js/behaviors.js: {}
08 dependencies:
09 - slide_down/slidedown
ajax_dblog/ajax_dblog.libraries.yml
01 slidedown:
02 version: VERSION
03 js:
04 js/slidedown-command.js: {}
05 dependencies:
06 - core/drupal.ajax
slide_down/slide_down.libraries.yml
Defining a dependency in the library on another library. The other library depends on the Ajax
Framework. Drupal will follow chain to include all depended JavaScript files.
Add Ajax to Elements
01 namespace Drupalajax_dblogController;
02 use DrupaldblogControllerDbLogController as ControllerBase;
03
04 class DbLogController extends ControllerBase {
05 // Override overview() method.
06 public function overview() {
07 $build = parent::overview();
08 // Alter the links for each log message.
09 foreach ($build['dblog_table']['#rows'] as &$row) {
10 // ...
11 // Build route parameters.
12 $params = array(
13 'method' => 'nojs',
14 //...
15 );
16 // Build link options.
17 $ops = array( 'attributes' => array(
18 'class' => array('use-ajax', 'dblog-event-link'),
19 ));
20 // Replace with a new link.
21 $row['data'][3] = Link::createFromRoute($txt,'ajax_dblog.event',$params,$ops);
22 }
23 return $build; ajax_dblogs/src/Controller/DbLogController.php
Need to have elements that will trigger an Ajax request. Rebuilding links on page to point to new route
(line #21). Links will have the class 'use­ajax' (line #18), which the Ajax Framework will look for.
Page still renders the same. However now includes Ajax Framework including the custom SlideDown
command. The message title links will now trigger an ajax request.
Create Ajax Request Endpoint
01 ajax_dblog.event:
02 path: '/admin/reports/dblog/{method}/event/{event_id}'
03 defaults:
04 _controller: 'Drupalajax_dblogControllerDbLogController::ajaxEventDetails'
05 requirements:
06 _permission: 'access site reports'
07 method: 'nojs|ajax'
ajax_dblog/ajax_dblog.routing.yml
/admin/reports/dblog/nojs/event/123
/admin/reports/dblog/ajax/event/123
Create an endpoint that will handle Ajax Requests. The ajax framework will replace 'nojs' with 'ajax' on
all request. Can use as a check to handle graceful degradation.
Return an AjaxResponse of Callback Commands
01 use DrupalCoreAjaxAjaxResponse;
02 use DrupalCoreAjaxAfterCommand;
03 use DrupalCoreAjaxRemoveCommand;
04 use Drupalslide_downAjaxSlideDownCommand;
05
06 class DbLogController extends ControllerBase {
07 // ...
08 public function ajaxEventDetails($method, $event_id) {
09 //...
10 if ($method == 'ajax') {
11 $event = parent::eventDetails($event_id);
12 $event_details = [ ... ];
13 // Create an AjaxResponse.
14 $response = new AjaxResponse();
15 // Remove old event details.
16 $response->addCommand(new RemoveCommand('.dblog-event-row'));
17 // Insert event details after event.
18 $response->addCommand(new AfterCommand('#dblog-event-' . $event_id, $event_details
19 // SlideDown event details.
20 $response->addCommand(new SlideDownCommand('#dblog-event-details-' . $event_id
21 }
22 // ...
23 } ajax_dblog/src/Controller/DbLogController.php
Have a method that is the endpoint for the Ajax request (line #8). Need to build an AjaxReponse object
(line #14). Will add commands to this response using the 'addCommand' method and creating a new
instance of the relevant Callback Command class (lines #16, #18, #20).
When a message title is clicked, the Ajax request is made. The endpoint builds an AjaxResponse of
commands and Drupal returns a JSON string.
Ajax Response
01 [
02 {
03 "command":"remove",
04 "selector":".dblog-event-row"
05 },
06 {
07 "command":"insert",
08 "method":"after",
09 "selector":"#dblog-event-32",
10 "data":"...",
11 "settings":null
12 },
13 {
14 "command":"slideDown",
15 "method":null,
16 "selector":"#dblog-event-details-32",
17 "duration":null
18 }
19 ]
The returned JSON array is parsed by Ajax Framework. Finds JavaScript function to execute and the
passes the object as the data for the response argument of the function.
To Use Callback Commands
Include the Ajax library and commands on the page.
Have endpoint that returns an AjaxResponse
Add commands to response using 'addCommand'
Resources
Drupal 8 Ajax Framework: bit.ly/Drupal8Ajax
This Presentation: bit.ly/D8DAjax
Presentation Slides: bit.ly/D8DAjaxSlides
Ajax Dblog: bit.ly/AjaxDblog
Creating Commands in D8: bit.ly/D8AjaxCmds
Feedback
@mikemiles86
 #Drupal8Day  @WeAreGenuine D8 Ajax Commands /  Michael Miles
Thank You!

More Related Content

PDF
Demystifying AJAX Callback Commands in Drupal 8
PDF
Demystifying Drupal AJAX Callback Commands
PDF
MidCamp 2016 - Demystifying AJAX Callback Commands in Drupal 8
PDF
Михаил Крайнюк - Form API + Drupal 8: Form and AJAX
PDF
NYCCAMP 2015 Demystifying Drupal AJAX Callback Commands
PDF
[스프링/Spring교육학원,자바교육,근로자교육,실업자교육추천학원_탑크리에듀]#6.스프링프레임워크 & 마이바티스 (Spring Framew...
PDF
#36.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_재직자환급교육,실업자교육,국비지원교육, 자바교육,구...
PDF
#18.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...
Demystifying AJAX Callback Commands in Drupal 8
Demystifying Drupal AJAX Callback Commands
MidCamp 2016 - Demystifying AJAX Callback Commands in Drupal 8
Михаил Крайнюк - Form API + Drupal 8: Form and AJAX
NYCCAMP 2015 Demystifying Drupal AJAX Callback Commands
[스프링/Spring교육학원,자바교육,근로자교육,실업자교육추천학원_탑크리에듀]#6.스프링프레임워크 & 마이바티스 (Spring Framew...
#36.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_재직자환급교육,실업자교육,국비지원교육, 자바교육,구...
#18.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...

What's hot (20)

PDF
#34.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자교육,국...
PPTX
Magento 2 | Declarative schema
PDF
Catalyst patterns-yapc-eu-2016
PDF
Upgrade your javascript to drupal 8
PPTX
Анатолий Поляков - Drupal.ajax framework from a to z
ZIP
First Steps in Drupal Code Driven Development
PPTX
Planbox Backbone MVC
PPTX
IndexedDB - Querying and Performance
PDF
Alfredo-PUMEX
PDF
td_mxc_rubyrails_shin
PDF
RicoLiveGrid
PDF
Drupal 8: Fields reborn
PDF
Sane Async Patterns
PPTX
An ADF Special Report
PDF
Reporting solutions for ADF Applications
PPT
Spring 3.x - Spring MVC
PDF
Spring mvc
PDF
L2 Web App Development Guest Lecture At University of Surrey 20/11/09
ODP
Java Spring MVC Framework with AngularJS by Google and HTML5
ODP
springmvc-150923124312-lva1-app6892
#34.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자교육,국...
Magento 2 | Declarative schema
Catalyst patterns-yapc-eu-2016
Upgrade your javascript to drupal 8
Анатолий Поляков - Drupal.ajax framework from a to z
First Steps in Drupal Code Driven Development
Planbox Backbone MVC
IndexedDB - Querying and Performance
Alfredo-PUMEX
td_mxc_rubyrails_shin
RicoLiveGrid
Drupal 8: Fields reborn
Sane Async Patterns
An ADF Special Report
Reporting solutions for ADF Applications
Spring 3.x - Spring MVC
Spring mvc
L2 Web App Development Guest Lecture At University of Surrey 20/11/09
Java Spring MVC Framework with AngularJS by Google and HTML5
springmvc-150923124312-lva1-app6892
Ad

Viewers also liked (20)

DOCX
Sample code to create files on your desktop using APEX
DOCX
Pharma24bd.DELAR QUOTATION
PDF
ICH S4 (Duration of Chronic Toxicity Testing in Animals (Rodent and Non Roden...
KEY
NinjaScript 2010-10-14
PPTX
Humanoid robot by mitesh kumar
DOCX
PPTX
Web 2 - Gastronomia
PDF
DIGITAL DIVIDE IN THAILAND: ANALYSIS AND RECOMMENDATIONS
PDF
RAJESH - GRAPHIC DESIGNER- RESUME 2016
PPTX
ION Bangladesh - ISOC Dhaka Chapter Welcome
PPTX
ION Bangladesh - IPv6 Experiences at Sri Lanka Telecom
PDF
BSSML16 L3. Clusters and Anomaly Detection
PPTX
Menus 5
PDF
The Flexibility of Drupal 8
PPT
Οι κάψουλες της Ιαπωνίας
PDF
A Ferrovia em Portugal
PDF
BSSML16 L2. Ensembles and Logistic Regressions
PDF
The Flexibility of Drupal 8 | DCNLights 2017
PPTX
Stunning Glasswing Butterfly - Greta oto
PPTX
The 2015 Sony world photography awards entries
Sample code to create files on your desktop using APEX
Pharma24bd.DELAR QUOTATION
ICH S4 (Duration of Chronic Toxicity Testing in Animals (Rodent and Non Roden...
NinjaScript 2010-10-14
Humanoid robot by mitesh kumar
Web 2 - Gastronomia
DIGITAL DIVIDE IN THAILAND: ANALYSIS AND RECOMMENDATIONS
RAJESH - GRAPHIC DESIGNER- RESUME 2016
ION Bangladesh - ISOC Dhaka Chapter Welcome
ION Bangladesh - IPv6 Experiences at Sri Lanka Telecom
BSSML16 L3. Clusters and Anomaly Detection
Menus 5
The Flexibility of Drupal 8
Οι κάψουλες της Ιαπωνίας
A Ferrovia em Portugal
BSSML16 L2. Ensembles and Logistic Regressions
The Flexibility of Drupal 8 | DCNLights 2017
Stunning Glasswing Butterfly - Greta oto
The 2015 Sony world photography awards entries
Ad

Similar to Drupal8Day: Demystifying Drupal 8 Ajax Callback commands (20)

PDF
11-DWR-and-JQuery
PDF
11-DWR-and-JQuery
PDF
Patterns Are Good For Managers
PDF
Ajax on drupal the right way - DrupalCamp Campinas, São Paulo, Brazil 2016
PDF
Drupal & javascript
PPTX
Serverless archtiectures
PDF
jQuery and Rails: Best Friends Forever
PDF
Introduction to Backbone.js for Rails developers
PDF
Intro to Laravel 4
PPTX
Soa development using javascript
PDF
Dependency Management with RequireJS
PPT
Sqlapi0.1
ODP
Javascript frameworks: Backbone.js
PDF
Rails is not just Ruby
PPTX
React, Flux and a little bit of Redux
PDF
PDF
Symfony2 - from the trenches
PDF
JQuery In Drupal
PDF
Viking academy backbone.js
PPSX
RequireJS
11-DWR-and-JQuery
11-DWR-and-JQuery
Patterns Are Good For Managers
Ajax on drupal the right way - DrupalCamp Campinas, São Paulo, Brazil 2016
Drupal & javascript
Serverless archtiectures
jQuery and Rails: Best Friends Forever
Introduction to Backbone.js for Rails developers
Intro to Laravel 4
Soa development using javascript
Dependency Management with RequireJS
Sqlapi0.1
Javascript frameworks: Backbone.js
Rails is not just Ruby
React, Flux and a little bit of Redux
Symfony2 - from the trenches
JQuery In Drupal
Viking academy backbone.js
RequireJS

More from Michael Miles (15)

PDF
Inclusive Design: Thinking beyond accessibility
PDF
How to Foster Team Success
PDF
How to Foster Team Success | Drupalcon 2017
PDF
Inclusive Design: Thinking Beyond Accessibility | NERDSummit 2017
PDF
Inclusive Design: Thinking Beyond Accessibility | DCNL 2017
PDF
INCLUSIVE DESIGN: Going beyond Accessibility
PDF
Inclusive Design
PDF
The Flexibility of Drupal
PDF
Badcamp 2015 - R.E.A.D: Four Steps for Selecting The Right Modules
PDF
The Flexibility of Drupal
PDF
The Flexibility of Drupal
PDF
Flcamp2015 - R.E.A.D: Four steps for selecting the right modules
PDF
R.E.A.D: Four steps for selecting the right modules Midcamp 2015
PDF
How to R.E.A.D: Steps for how to select the correct module @NEWDCamp 2014
PDF
To Patch or Custom: How to decide when to patch a contrib module or go custom...
Inclusive Design: Thinking beyond accessibility
How to Foster Team Success
How to Foster Team Success | Drupalcon 2017
Inclusive Design: Thinking Beyond Accessibility | NERDSummit 2017
Inclusive Design: Thinking Beyond Accessibility | DCNL 2017
INCLUSIVE DESIGN: Going beyond Accessibility
Inclusive Design
The Flexibility of Drupal
Badcamp 2015 - R.E.A.D: Four Steps for Selecting The Right Modules
The Flexibility of Drupal
The Flexibility of Drupal
Flcamp2015 - R.E.A.D: Four steps for selecting the right modules
R.E.A.D: Four steps for selecting the right modules Midcamp 2015
How to R.E.A.D: Steps for how to select the correct module @NEWDCamp 2014
To Patch or Custom: How to decide when to patch a contrib module or go custom...

Recently uploaded (20)

PDF
The New Creative Director: How AI Tools for Social Media Content Creation Are...
PPT
tcp ip networks nd ip layering assotred slides
PDF
Decoding a Decade: 10 Years of Applied CTI Discipline
PPTX
522797556-Unit-2-Temperature-measurement-1-1.pptx
PDF
Unit-1 introduction to cyber security discuss about how to secure a system
PPTX
presentation_pfe-universite-molay-seltan.pptx
PPTX
international classification of diseases ICD-10 review PPT.pptx
PDF
Sims 4 Historia para lo sims 4 para jugar
PPTX
Slides PPTX World Game (s) Eco Economic Epochs.pptx
PPTX
PptxGenJS_Demo_Chart_20250317130215833.pptx
PDF
Tenda Login Guide: Access Your Router in 5 Easy Steps
PPTX
Module 1 - Cyber Law and Ethics 101.pptx
PDF
Triggering QUIC, presented by Geoff Huston at IETF 123
PDF
RPKI Status Update, presented by Makito Lay at IDNOG 10
PDF
An introduction to the IFRS (ISSB) Stndards.pdf
PDF
Automated vs Manual WooCommerce to Shopify Migration_ Pros & Cons.pdf
PDF
Testing WebRTC applications at scale.pdf
PDF
APNIC Update, presented at PHNOG 2025 by Shane Hermoso
PPTX
Funds Management Learning Material for Beg
PDF
Paper PDF World Game (s) Great Redesign.pdf
The New Creative Director: How AI Tools for Social Media Content Creation Are...
tcp ip networks nd ip layering assotred slides
Decoding a Decade: 10 Years of Applied CTI Discipline
522797556-Unit-2-Temperature-measurement-1-1.pptx
Unit-1 introduction to cyber security discuss about how to secure a system
presentation_pfe-universite-molay-seltan.pptx
international classification of diseases ICD-10 review PPT.pptx
Sims 4 Historia para lo sims 4 para jugar
Slides PPTX World Game (s) Eco Economic Epochs.pptx
PptxGenJS_Demo_Chart_20250317130215833.pptx
Tenda Login Guide: Access Your Router in 5 Easy Steps
Module 1 - Cyber Law and Ethics 101.pptx
Triggering QUIC, presented by Geoff Huston at IETF 123
RPKI Status Update, presented by Makito Lay at IDNOG 10
An introduction to the IFRS (ISSB) Stndards.pdf
Automated vs Manual WooCommerce to Shopify Migration_ Pros & Cons.pdf
Testing WebRTC applications at scale.pdf
APNIC Update, presented at PHNOG 2025 by Shane Hermoso
Funds Management Learning Material for Beg
Paper PDF World Game (s) Great Redesign.pdf

Drupal8Day: Demystifying Drupal 8 Ajax Callback commands

  • 6. Callback Structure: JavaScript 01 (function ($, window, Drupal, drupalSettings) { 02 'use strict'; 03 /** 04 * [commandName description] 05 * 06 * @param {Drupal.Ajax} [ajax] 07 * @param {object} response 08 * @param {number} [status] 09 */ 10 Drupal.AjaxCommands.prototype.[commandName] = function(ajax, response, status){ 11 12 // Custom javascript goes here ... 13 14 } 15 16 })(jQuery, this, Drupal, drupalSettings); [module]/js/[javascript].js Example of the structure for the JavaScript half of a callback command as defined in a module.
  • 8. Callback Structure: PHP 01 namespace Drupal[module]Ajax 02 use DrupalCoreAjaxCommandInterface; 03 04 // An Ajax command for calling [commandName]() JavaScript method. 05 class [CommandName]Command implements CommandInterface { 06 07 // Implements DrupalCoreAjaxCommandInterface:render(). 08 public function render() { 09 return array( 10 'command' => '[commandName]', // Name of JavaScript Method. 11 // other response arguments... 12 ); 13 } 14 } [module]/src/Ajax/[CommandName]Command.php Example of the structure for the PHP half of a callback command as defined in a module.
  • 9. Core Example: Remove 01 Drupal.AjaxCommands.prototype = { 02 // ... 03 /** 04 * Command to remove a chunk from the page. 05 * 06 * @param {Drupal.Ajax} [ajax] 07 * @param {object} response 08 * @param {string} response.selector 09 * @param {object} [response.settings] 10 * @param {number} [status] 11 */ 12 remove: function (ajax, response, status) { 13 var settings = response.settings || ajax.settings || drupalSettings; 14 $(response.selector).each(function () { 15 Drupal.detachBehaviors(this, settings); 16 }) 17 .remove(); 18 }, 19 //... misc/ajax.js The JavaScript function for the core 'remove' callback command. It is basically a wrapper for the jQuery 'remove' method.
  • 10. Core Example: RemoveCommand 01 namespace DrupalCoreAjax; 02 use DrupalCoreAjaxCommandInterface; 03 /** 04 * Ajax command for calling the jQuery remove() method. 05 * ... 06 */ 07 class RemoveCommand Implements CommandInterface { 08 // ... 09 /** 10 * Implements DrupalCoreAjaxCommandInterface:render(). 11 */ 12 public function render() { 13 return array( 14 'command' => 'remove', 15 'selector' => $this->selector, 16 ); 17 } 18 } core/lib/Drupal/Core/Ajax/RemoveCommand.php The PHP class for the core 'remove' callback command. Implements CommandInterface, so it must define the method 'render' that returns an associative array.
  • 11. PHP 01 //... 02 public function render() { 03 return array( 04 'command' => 'remove', 05 'selector' => $this->selector, 06 ); 07 } core/lib/Drupal/Core/Ajax/RemoveCommand.php JavaScript 01 //... 02 remove: function (ajax, response, status) { 03 var settings = response.settings || ajax.settings || drupalSettings; 04 $(response.selector).each(function () { 05 Drupal.detachBehaviors(this, settings); 06 }) 07 .remove(); 08 }, misc/ajax.js Can see how the two halfs are tied together. Value on line #4 of PHP matches JavaScript function name defined on line #2 in JavaScript. Passed CSS selector on line #5 in PHP is used on line #4 in JavaScript.
  • 15. Create a Module 01 name: 'Slide Down Command' 02 type: module 03 description: Provides an Ajax Callback command for the jQuery SlideDown method. 04 package: other 05 core: 8.x slide_down/slide_down.info.yml Custom Ajax callback commands must be defined in a module.
  • 16. Create JavaScript Function 01 (function ($, window, Drupal, drupalSettings) { 02 03 'use strict'; 04 05 // Command to Slide Down page elements. 06 Drupal.AjaxCommands.prototype.slideDown = function(ajax, response, status){ 07 // Get duration if sent, else use default of slow. 08 var duration = response.duration ? response.duration : "slow"; 09 // slide down the selected element(s). 10 $(response.selector).slideDown(duration); 11 } 12 })(jQuery, this, Drupal, drupalSettings); slide_down/js/slidedown-command.js Attach a JavaScript function to the AjaxCommands object provided by the Ajax Framework. Accepts the three arguments and is a wrapper for the jQuery method.
  • 17. Create Asset Library 01 slidedown: 02 version: VERSION 03 js: 04 js/slidedown-command.js; {} 05 dependencies: 06 - core/drupal.ajax slide_down/slide_down.libraries.yml In Drupal 8 custom JavaScript files must be added to an asset library to be able to be included on a page.
  • 18. Create PHP Class 01 namespace Drupalslide_downAjax; 02 use DrupalCoreAjaxCommandInterface; 03 04 class SlideDownCommand implements CommandInterface { 05 // ... 06 // Constructs an SlideDownCommand object. 07 public function __construct($selector, $duration = NULL) { 08 $this->selector = $selector; 09 $this->duration = $duration; 10 } 11 12 // Implements DrupalCoreAjaxCommandInterface:render(). 13 public function render() { 14 return array( 15 'command' => 'slideDown', 16 'method' => NULL, 17 'selector' => $this->selector, 18 'duration' => $this->duration, 19 ); 20 } 21 } slide_down/src/Ajax/SlideDownCommand.php Create a PHP class that implements CommandInterface. Must define a 'render' method and return an associative array. In the array, pass the element with key of 'command' and value being the name of the JavaScript function and any repsonse data.
  • 19. To Create a Callback Command: Create a module Attach JavaScript function to 'Drupal.AjaxCommands.prototype' Define an asset library Create PHP class that implements 'CommandInterface'
  • 22. Add Ajax Library to Page 01 use DrupaldblogControllerDbLogController as ControllerBase; 02 03 class DbLogController extends ControllerBase { 04 // Override overview() method. 05 public function overview() { 06 $build = parent::overview(); 07 // ... 08 // Add custom library. 09 $build['#attached']['library'][] = 'ajax_dblog/ajax-dblog'; 10 return $build; 11 } 12 // ... 13 } ajax_dblog/src/Controller/DbLogController.php Need to attach custom library onto page so that custom JavaScript and Ajax Framework is included.
  • 23. 01 ajax-dblog: 02 version: VERSION 03 css: 04 component: 05 css/ajax_dblog.module.css: {} 06 js: 07 js/behaviors.js: {} 08 dependencies: 09 - slide_down/slidedown ajax_dblog/ajax_dblog.libraries.yml 01 slidedown: 02 version: VERSION 03 js: 04 js/slidedown-command.js: {} 05 dependencies: 06 - core/drupal.ajax slide_down/slide_down.libraries.yml Defining a dependency in the library on another library. The other library depends on the Ajax Framework. Drupal will follow chain to include all depended JavaScript files.
  • 24. Add Ajax to Elements 01 namespace Drupalajax_dblogController; 02 use DrupaldblogControllerDbLogController as ControllerBase; 03 04 class DbLogController extends ControllerBase { 05 // Override overview() method. 06 public function overview() { 07 $build = parent::overview(); 08 // Alter the links for each log message. 09 foreach ($build['dblog_table']['#rows'] as &$row) { 10 // ... 11 // Build route parameters. 12 $params = array( 13 'method' => 'nojs', 14 //... 15 ); 16 // Build link options. 17 $ops = array( 'attributes' => array( 18 'class' => array('use-ajax', 'dblog-event-link'), 19 )); 20 // Replace with a new link. 21 $row['data'][3] = Link::createFromRoute($txt,'ajax_dblog.event',$params,$ops); 22 } 23 return $build; ajax_dblogs/src/Controller/DbLogController.php Need to have elements that will trigger an Ajax request. Rebuilding links on page to point to new route (line #21). Links will have the class 'use­ajax' (line #18), which the Ajax Framework will look for.
  • 26. Create Ajax Request Endpoint 01 ajax_dblog.event: 02 path: '/admin/reports/dblog/{method}/event/{event_id}' 03 defaults: 04 _controller: 'Drupalajax_dblogControllerDbLogController::ajaxEventDetails' 05 requirements: 06 _permission: 'access site reports' 07 method: 'nojs|ajax' ajax_dblog/ajax_dblog.routing.yml /admin/reports/dblog/nojs/event/123 /admin/reports/dblog/ajax/event/123 Create an endpoint that will handle Ajax Requests. The ajax framework will replace 'nojs' with 'ajax' on all request. Can use as a check to handle graceful degradation.
  • 27. Return an AjaxResponse of Callback Commands 01 use DrupalCoreAjaxAjaxResponse; 02 use DrupalCoreAjaxAfterCommand; 03 use DrupalCoreAjaxRemoveCommand; 04 use Drupalslide_downAjaxSlideDownCommand; 05 06 class DbLogController extends ControllerBase { 07 // ... 08 public function ajaxEventDetails($method, $event_id) { 09 //... 10 if ($method == 'ajax') { 11 $event = parent::eventDetails($event_id); 12 $event_details = [ ... ]; 13 // Create an AjaxResponse. 14 $response = new AjaxResponse(); 15 // Remove old event details. 16 $response->addCommand(new RemoveCommand('.dblog-event-row')); 17 // Insert event details after event. 18 $response->addCommand(new AfterCommand('#dblog-event-' . $event_id, $event_details 19 // SlideDown event details. 20 $response->addCommand(new SlideDownCommand('#dblog-event-details-' . $event_id 21 } 22 // ... 23 } ajax_dblog/src/Controller/DbLogController.php Have a method that is the endpoint for the Ajax request (line #8). Need to build an AjaxReponse object (line #14). Will add commands to this response using the 'addCommand' method and creating a new instance of the relevant Callback Command class (lines #16, #18, #20).
  • 29. Ajax Response 01 [ 02 { 03 "command":"remove", 04 "selector":".dblog-event-row" 05 }, 06 { 07 "command":"insert", 08 "method":"after", 09 "selector":"#dblog-event-32", 10 "data":"...", 11 "settings":null 12 }, 13 { 14 "command":"slideDown", 15 "method":null, 16 "selector":"#dblog-event-details-32", 17 "duration":null 18 } 19 ] The returned JSON array is parsed by Ajax Framework. Finds JavaScript function to execute and the passes the object as the data for the response argument of the function.
  • 30. To Use Callback Commands Include the Ajax library and commands on the page. Have endpoint that returns an AjaxResponse Add commands to response using 'addCommand'