SlideShare a Scribd company logo
Demystifying Drupal
AJAX Callback Commands
http://nerdsummit.org/node/2068
NERDsummit 2015
#NERDsummit
Goals of this Session
Explain what AJAX callback commands are
Demonstrate how to use AJAX callback commands
Outline how to create AJAX callback commands
Michael Miles
From: Boston, MA USA
Work:   @WeAreGenuine(.com)
(I have stickers!)
Genuine
Exp: Working with Drupal since 2008.
Acquia Grand Master.  2014 Acquia MVP.
Twitter: @mikemiles86 Drupal.org: mikemiles86 
All the Places: mikemiles86
Warning About Example Code
There is example code
Some coding standards ignored for presentation purposes
Drupal 8 code still subject to change
What Commands Are
From a High Level
The response of AJAX request
PHP code to instruct JavaScript functions
A JavaScript function attached to an object
Defined by Drupal core or modules
17 AJAX callback commands in Drupal 7
Example: The "Remove" Command
Using the "examples" module (available on Drupal.org), showing using the 'remove' AJAX Callback
command. The checkbox is checked, which makes an AJAX request, which returns the command to
remove the element with the sample text.
On the Client Side [D7]
A function on the 'Drupal.ajax.prototype.commands' object
Receives 'ajax', 'response' and 'status' arguments
A wrapper for additional javascript
// Provide a series of commands that the server can request the client perform.
Drupal.ajax.prototype.commands = {
//...
/**
* Command to remove a chunk from the page.
*/
remove: function (ajax, response, status) {
var settings = response.settings || ajax.settings || Drupal.settings;
Drupal.detachBehaviors($(response.selector), settings);
$(response.selector).remove();
},
//...
}
misc/ajax.js
On the Server Side [D7]
A PHP function which returns an associative array
Array must have an element with key of 'command'
The value is the name of a JavaScript function
Additional array elements set as response data
/**
* Creates a Drupal Ajax 'remove' command.
*/
function ajax_command_remove($selector) {
return array(
'command' => 'remove',
'selector' => $selector,
);
}
includes/ajax.inc
How to Use Commands
Example Scenario
 As a user
When I navigate to the 'my-messages' page
Then I see a list of my unread messages
And I see a list of my read messages
When I click on an unread message
Then the full messaged is retrieved from the server
And I see the content of my message
And the message is removed from the unread messages list
And the message is added to the read messages list
Example Scenario. Have a page that lists messages to read. When a message subject is clicked, an AJAX
request is made to retrieve the message. The server returns an array of commands to run, which
updates the page with the selected message.
To Use Commands...
1.  Include Drupal AJAX JavaScript library
2.  Attach AJAX to page elements
3.  Define a callback path and function
Returns a render array of commands [D7]
1. Include Drupal AJAX library
// Render a page of messages.
function mymodule_messages_page() {
// Include AJAX library.
drupal_add_library('system', 'drupal.ajax');
// Create inital page content.
$content = theme_item_list(array(
'title' => t('Unread Messages'),
'type' => 'ul',
'attributes' => array( 'id' => 'unread-msgs'),
'items' => mymodule_messages_list(mymodule_get_unread_messages()),
));
$content .= '<div id="current-msg"><h2></h2><p></p></div>';
$content .= theme_item_list(array(
'title' => t('Read Messages'),
'type' => 'ul',
'attributes' => array('id' => 'read-msgs'),
'items' => mymodule_messages_list(mymodule_get_read_messages(), FALSE),
));
return $content;
}
mymodule/mymodule.module
Function to build a page of messages. On line #4, using the drupal_add_librry() function to include the
AJAX library on the page.
2. Attach AJAX to page elements
// Return array of message titles for use in a list.
function mymodule_messages_list($messages, $display_link = TRUE) {
$list_items = array();
foreach ($messages as $mid => $msg) {
// Build link to AJAX callback to load message.
$link = l($msg->subject, 'read-message-callback/nojs/' . $mid, array(
// Add class to link so Drupal knows to use AJAX.
'attributes' => array('class' => array('use-ajax')),
));
// Create list item for message.
$list_items[] = array(
'id' => 'msg-' . $mid,
// Set data to read message link or just message subject.
'data' => $display_link ? $link : $msg->subject,
);
}
return $list_items;
}
mymodule/mymodule.module
Function to build a list of messages. On line #6, creating a link element which links to our callback path.
On line #8, adding the class 'use­ajax' so AJAX framework knows to serve link with an AJAX request.
3.a Define a callback path
// Implements hook_menu().
function mymodule_menu() {
$items = array();
//.. Other menu items.
// None JS callback, for graceful degredation.
$items['read-message-callback/nojs/%'] = array(
'title' => 'AJAX Callback to Read Message',
'access arguments' => array('access content'),
'page callback' => 'mymodule_read_message_callback',
'page arguments' => array(1,2),
'type' => MENU_CALLBACK,
);
// Create AJAX callback. Add ajax_delivery callback.
$items['read-message-callback/ajax/%'] = array(
'delivery callback' => 'ajax_deliver',
) + $items['read-message-callback/nojs/%'];
return $items;
}
mymodule/mymodule.module
Creating two menu items for callback functions. The first is for handling graceful degredation when
reached outside an AJAX Request. The second is the AJAX callback, which add a delivery callback of
"ajax_callback" so Drupal know to return an AJAX Response object.
3.b Return array of commands using a render array [D7]
// AJAX Callback to read a message.
function mymodule_read_message_callback($method, $mid) {
$message = mymodule_load_message($mid);
// @TODO: Graceful degredation if not from ajax method or if no message.
$commands = array(
// Replace content of current message subject.
ajax_command_html('#current-msg h2', $message->subject),
// Replace content of current message body.
ajax_command_html('#current-msg p', $message->content),
// Remove message from unread list.
ajax_command_remove('#msg-' . $mid),
// Add message to read list
ajax_command_append('#read-msgs', '<li>' . $message->subject . '</li>'),
);
// Return an AJAX render array.
return array(
'#type' => 'ajax',
'#commands' => $commands,
);
}
mymodule/mymodule.module
Lines #5 thru #14, building an array of Core AJAX Callback commands. Each mapps to a javascript
function. Line #16 building a render array of type 'ajax'. Drupal will package into JSON and send back to
the client.
Creating Custom Commands
To Create a Command...
1.  Add a function to the Drupal ajax command JavaScript object
2.  Write PHP code that returns an associative array.
Must have an element with key of 'command'
Value is name of the JavaScript function
Additional elements for response data
That's it.
A Custom Command in Drupal 7
1.  Add a function to 'Drupal.ajax.prototype.commands'
2.  Define a PHP function to return an array
1. Add a function to 'Drupal.ajax.prototype.commands'
(function($, Drupal) {
// Add new command for reading a message.
Drupal.ajax.prototype.commands.readMessage = function(ajax, response, status){
// Place content in current-msg div.
$('#current-msg h2').html(response.subject);
$('#current-msg p').html(response.content);
// Remove from unread list.
$('#msg-' + response.mid).remove();
// Add message to read list.
$('#read-msgs').append('<li>' + response.subject + '</li>');
}
})(jQuery, Drupal);
mymodule/js/commands.js
Attach a new 'readMessage' command to the Drupal AJAX Commands JavaScript object. Function takes
in the 3 arguments "ajax", "response" & "status". Wraps jQuery functions to display a message on the
page.
2. Define a PHP function to return an associative array
/**
* AJAX command to read a message.
*/
function mymodule_command_read_message($message) {
return array(
'command' => 'readMessage',
'mid' => $message->mid,
'subject' => $message->subject,
'content' => $message->content,
);
}
mymodule/mymodule.module
PHP function that mapps to the new JavaScript 'readMessage' array. Returns an associative array, with
an element that has a key of 'command' and value of the JavaScript function name 'readMessage'. Then
additional elements to be sent as request data.
Using a custom command...
1.  Tell Drupal to include custom JavaScript
2.  Return custom command in callback function
Again...that's it.
Using a Custom Command in Drupal 7
1.  Use drupal_add_js() to include custom JavaScript on page
2.  Add command to render array returned by callback
1. Use drupal_add_js() to include custom JavaScript on page
// Render a page of my messages
function mymodule_messages_page() {
// Include AJAX library.
drupal_add_library('system', 'drupal.ajax');
// Include custom JavaScript.
drupal_add_js(drupal_get_path('module', 'mymodule') . '/js/commands.js');
// .. Build $content.
return $content;
}
mymodule/mymodule.module
The example function for creating the messages page. In addition to adding the Drupal AJAX library on
line #4 also using drupal_add_js() to include custom javascript file on line #6.
2. Add command to render array returned by callback
// AJAX Callback to read a message.
function mymodule_read_message_callback($method, $mid) {
$message = mymodule_load_message($mid);
// @TODO: Graceful degredation if not from ajax method or if no message.
$commands = array(
// Call the readMessage javascript function.
mymodule_command_read_message($message),
);
// Return an AJAX render array.
return array(
'#type' => 'ajax',
'#commands' => $commands,
);
}
mymodule/mymodule.module
The example callback function that returns an AJAX render array. Commands array on lines #5 thru #8,
only returns a single command. The new custom command that was created.
AJAX Commands in Drupal 8
Changes to AJAX Commands
22 AJAX callback commands in Drupal 8
JavaScript attatches to 'Drupal.AjaxCommands.prototype' object
A PHP object that implements CommandInterface
Must implement 'render' method
Example: The "Remove" Command
Using the "examples" module (available on Drupal.org), showing using the 'remove' AJAX Callback
command. The checkbox is checked, which makes an AJAX request, which returns the command to
remove the element with the sample text.
A function on the 'Drupal.AjaxCommands.prototype' object
/**
* Provide a series of commands that the client will perform.
*/
Drupal.AjaxCommands.prototype = {
//...
/**
* Command to remove a chunk from the page.
*/
remove: function (ajax, response, status) {
var settings = response.settings || ajax.settings || drupalSettings;
$(response.selector).each(function () {
Drupal.detachBehaviors(this, settings);
}).remove();
},
//...
}
misc/ajax.js
An object that implements CommandInterface
Must implement 'render' method
namespace DrupalCoreAjax;
use DrupalCoreAjaxCommandInterface;
// AJAX command for calling the jQuery remove() method.
class RemoveCommand Implements CommandInterface {
protected $selector;
// Constructs a RemoveCommand object.
public function __construct($selector) {
$this->selector = $selector;
}
// Implements DrupalCoreAjaxCommandInterface:render().
public function render() {
return array(
'command' => 'remove',
'selector' => $this->selector,
);
}
}
core/lib/Drupal/Core/Ajax/RemoveCommand.php
To Use Commands in Drupal 8
1.  Include Drupal AJAX JavaScript library
Must attach to a render array
2.  Attach AJAX to page elements
3.  Define a callback path and function
Returns an AjaxResponse object
Example Scenario. Have a page that lists messages to read. When a message subject is clicked, an AJAX
request is made to retrieve the message. The server returns an array of commands to run, which
updates the page with the selected message.
Attach library to a render array
namespace DrupalmymoduleController;
use DrupalCoreControllerControllerBase;
class MyModuleController extends ControllerBase {
// ...
// Render a page of my messages
public function messagesPage() {
// ... build $content
// Create render array.
$page[] = array(
'#type' => 'markup',
'#markup' => $content,
);
// Attach JavaScript library.
$page['#attached']['library'][] = 'core/drupal.ajax';
return $page;
}
// ...
}
mymodule/src/Controller/MyModuleController.php
Function for building messages page is now using a render array. to the '#attached', 'library' array of
that render array, declaring the drupal.ajax library to be included.
Callback returns commands using an AJAXResponse() [D8]
namespace DrupalmymoduleController;
use DrupalCoreControllerControllerBase;
class MyModuleController extends ControllerBase {
// ...
// AJAX Callback to read a message.
public function readMessageCallback($method, $mid) {
$msg = mymodule_load_message($mid);
// Create AJAX Response object.
$response = new AjaxResponse();
// Replace content of current message subject.
$response->addCommand(new HtmlCommand('#current-msg h2', $msg->subject));
// Replace content of current message body.
$response->addCommand(new HtmlCommand('#current-msg p', $msg->content));
// Remove message from unread list.
$response->addCommand(new RemoveCommand('#msg-' . $mid));
// Add message to read list.
$item = '<li>' . $msg->subject . '</li>';
$response->addCommand(new AppendCommand('#read-msgs', $item));
// Return ajax response.
return $response;
}
mymodule/src/Controller/MyModuleController.php
Returning an AjaxResponse object instead of a render array like in Drupal 7. AjaxResponse has an
'addCommand' method, which takes the argument of a command object.
Custom Commands in Drupal 8
1.  Add function to 'Drupal.AjaxCommands.prototype'
2.  Define a command object that implements CommandInterface
1. Add function to 'Drupal.AjaxCommands.prototype'
(function($, Drupal) {
/**
* Add new command for reading a message.
*/
Drupal.AjaxCommands.prototype.readMessage = function(ajax, response, status){
// Place content in current-msg div.
$('#current-msg h2').html(response.subject);
$('#current-msg p').html(response.content);
// Remove from unread list.
$('#msg-' + response.mid).remove();
// Add message to read list.
$('#read-msgs').append('<li>' + response.subject + '</li>');
}
})(jQuery, Drupal);
mymodule/js/commands.js
Adding the custom 'readMessage' function to the Drupal 8 JavaScript AJAX Commands object. Still takes
the same three arguments as in Drupal 7.
2. Define command object that implements CommandInterface
namespace DrupalmymoduleAjax;
use DrupalCoreAjaxCommandInterface;
class ReadMessageCommand implements CommandInterface {
protected $message;
// Constructs a ReadMessageCommand object.
public function __construct($message) {
$this->message = $message;
}
// Implements DrupalCoreAjaxCommandInterface:render().
public function render() {
return array(
'command' => 'readMessage',
'mid' => $this->message->mid,
'subject' => $this->message->subject,
'content' => $this->message->content,
);
}
}
mymodule/src/Ajax/ReadMessageCommand.php
Creating a Command object which implements the CommandInterface. Must declare a 'render' method,
which will return an associative array. This associative array must have an element with the key of
'command' and value of the JavaScript function to run.
Using a Custom Command in Drupal 8
1.  Tell Drupal about custom JavaScript library
2.  Attach library to a render array
3.  Add command to AjaxResponse object in callback
1. Tell Drupal about custom JavaScript library
mymodule.commands:
version: VERSION
js:
js/commands.js: {}
dependencies:
- core/drupal.ajax
mymodule/mymodule.libraries.yml
Must tell Drupal about custom library with a libraries.yml file. Provide an Asset library name, lists all the
js files needed, and any dependencies on other libraries.
2. Attach library to a render array
namespace DrupalmymoduleController;
use DrupalCoreControllerControllerBase;
class MyModuleController extends ControllerBase {
// ...
// Render a page of my messages
public function messagesPage() {
// .. build $content
// Create render array.
$page[] = array(
'#type' => 'markup',
'#markup' => $content,
);
// Attach JavaScript library.
$page['#attached']['library'][] = 'mymodule/mymodule.commands';
return $page;
}
// ...
}
mymodule/mymodule.module
Function for building messages page is now using a render array. to the '#attached', 'library' array of
that render array, including the custom library. No longer including the AJAX library, as Drupal will know
to include it from the libraries.yml file.
3. Add command to AjaxResponse object in callback
namespace DrupalmymoduleController;
use DrupalCoreControllerControllerBase;
class MyModuleController extends ControllerBase {
// ...
// AJAX Callback to read a message.
public function readMessageCallback($method, $mid) {
$msg = mymodule_load_message($mid);
// Create AJAX Response object.
$response = new AjaxResponse();
// Call the readMessage javascript function.
$response->addCommand( new ReadMessageCommand($msg));
);
// Return ajax response.
return $response;
}
//...
}
mymodule/mymodule.module
Returning an AjaxResponse object instead of adding the core commands, just adding the new custom
command using the 'addCommand' method.
Let's Review
AJAX Callback Commands Are...
Returned by all AJAX Framework requests
PHP abstraction for JavaScript functions
Defined by core and modules
To Use AJAX Callback Commands...
Include Drupal AJAX JavaScript library
Attach AJAX to page elements
Have server side callback return array of commands
To Create AJAX Callback Commands...
Add function to Drupal ajax command JavaScript object.
Write PHP code to return associative array with a 'command' key
To Use Custom AJAX Callback
Commands...
Include custom JavaScript
Include custom command in callback function
Resources
Drupal AJAX Framework: bit.ly/DrupalAJAX
This Presentation: bit.ly/NERD15ajax
Presentation Slides: bit.ly/NERD15ajaxSlides
Example Code for Drupal 7: bit.ly/NERD15ajaxEx
Creating Commands in D8: bit.ly/D8AjaxCmds
Send me feedback!
@mikemiles86
#NERDsummit
 #NERDsummit  @WeAreGenuineAJAX Callback Commands /  @mikemiles86
Thank You!
Questions?

More Related Content

What's hot

Aem Training Tutorials for Beginners
Aem  Training Tutorials for BeginnersAem  Training Tutorials for Beginners
Aem Training Tutorials for Beginners
Shrinivas AEM Online Training
 
How to Enable Change Management with Jira Service Management
How to Enable Change Management with Jira Service ManagementHow to Enable Change Management with Jira Service Management
How to Enable Change Management with Jira Service Management
Cprime
 
Git Anti-Patterns - Extended Version With 28 Common Anti-Patterns) - SCTurkey...
Git Anti-Patterns - Extended Version With 28 Common Anti-Patterns) - SCTurkey...Git Anti-Patterns - Extended Version With 28 Common Anti-Patterns) - SCTurkey...
Git Anti-Patterns - Extended Version With 28 Common Anti-Patterns) - SCTurkey...
Lemi Orhan Ergin
 
Essentials of enterprise architecture tools
Essentials of enterprise architecture toolsEssentials of enterprise architecture tools
Essentials of enterprise architecture tools
iasaglobal
 
AWS와 함께 한 쿠키런 서버 Re-architecting 사례 (Gaming on AWS)
AWS와 함께 한 쿠키런 서버 Re-architecting 사례 (Gaming on AWS)AWS와 함께 한 쿠키런 서버 Re-architecting 사례 (Gaming on AWS)
AWS와 함께 한 쿠키런 서버 Re-architecting 사례 (Gaming on AWS)Brian Hong
 
TOGAF 9 Architectural Artifacts
TOGAF 9  Architectural ArtifactsTOGAF 9  Architectural Artifacts
TOGAF 9 Architectural Artifacts
Maganathin Veeraragaloo
 
DDD patterns that were not in the book
DDD patterns that were not in the bookDDD patterns that were not in the book
DDD patterns that were not in the book
Cyrille Martraire
 
Gestión de Cambios de BBDD con LiquiBase
Gestión de Cambios de BBDD con LiquiBaseGestión de Cambios de BBDD con LiquiBase
Gestión de Cambios de BBDD con LiquiBase
Paulo Clavijo
 
The Acord Framework - An Insurance Enterprise Architecture (2011).pdf
The Acord Framework - An Insurance Enterprise Architecture (2011).pdfThe Acord Framework - An Insurance Enterprise Architecture (2011).pdf
The Acord Framework - An Insurance Enterprise Architecture (2011).pdf
havoc2003
 
The Ultimate Logging Architecture - You KNOW you want it!
The Ultimate Logging Architecture - You KNOW you want it!The Ultimate Logging Architecture - You KNOW you want it!
The Ultimate Logging Architecture - You KNOW you want it!
Michele Leroux Bustamante
 
Togaf 9.2 Introduction
Togaf 9.2 IntroductionTogaf 9.2 Introduction
Togaf 9.2 Introduction
Mohamed Zakarya Abdelgawad
 
GraphQL as an alternative approach to REST (as presented at Java2Days/CodeMon...
GraphQL as an alternative approach to REST (as presented at Java2Days/CodeMon...GraphQL as an alternative approach to REST (as presented at Java2Days/CodeMon...
GraphQL as an alternative approach to REST (as presented at Java2Days/CodeMon...
luisw19
 
Understanding and Applying The Open Group Architecture Framework (TOGAF)
Understanding and Applying The Open Group Architecture Framework (TOGAF)Understanding and Applying The Open Group Architecture Framework (TOGAF)
Understanding and Applying The Open Group Architecture Framework (TOGAF)
Nathaniel Palmer
 
[Atlassian in 부산]Git을 이용한 형상관리 전략_투씨드
[Atlassian in 부산]Git을 이용한 형상관리 전략_투씨드[Atlassian in 부산]Git을 이용한 형상관리 전략_투씨드
[Atlassian in 부산]Git을 이용한 형상관리 전략_투씨드
Atlassian 대한민국
 
Software Architecture: views and viewpoints
Software Architecture: views and viewpointsSoftware Architecture: views and viewpoints
Software Architecture: views and viewpoints
Henry Muccini
 
Doors hints and tips schema
Doors hints and tips schemaDoors hints and tips schema
Doors hints and tips schema
Hazel Woodcock
 
Enterprise Architecture Toolkit Overview
Enterprise Architecture Toolkit OverviewEnterprise Architecture Toolkit Overview
Enterprise Architecture Toolkit Overview
Mike Walker
 
Software architecture document
Software architecture documentSoftware architecture document
Software architecture document
Haidar Arya
 
A pattern language for microservices - June 2021
A pattern language for microservices - June 2021 A pattern language for microservices - June 2021
A pattern language for microservices - June 2021
Chris Richardson
 
Jira + Confluence + Bitbucket으로 이슈 트래킹 걸음마 떼기
Jira + Confluence + Bitbucket으로 이슈 트래킹 걸음마 떼기Jira + Confluence + Bitbucket으로 이슈 트래킹 걸음마 떼기
Jira + Confluence + Bitbucket으로 이슈 트래킹 걸음마 떼기
KyeongmanKang
 

What's hot (20)

Aem Training Tutorials for Beginners
Aem  Training Tutorials for BeginnersAem  Training Tutorials for Beginners
Aem Training Tutorials for Beginners
 
How to Enable Change Management with Jira Service Management
How to Enable Change Management with Jira Service ManagementHow to Enable Change Management with Jira Service Management
How to Enable Change Management with Jira Service Management
 
Git Anti-Patterns - Extended Version With 28 Common Anti-Patterns) - SCTurkey...
Git Anti-Patterns - Extended Version With 28 Common Anti-Patterns) - SCTurkey...Git Anti-Patterns - Extended Version With 28 Common Anti-Patterns) - SCTurkey...
Git Anti-Patterns - Extended Version With 28 Common Anti-Patterns) - SCTurkey...
 
Essentials of enterprise architecture tools
Essentials of enterprise architecture toolsEssentials of enterprise architecture tools
Essentials of enterprise architecture tools
 
AWS와 함께 한 쿠키런 서버 Re-architecting 사례 (Gaming on AWS)
AWS와 함께 한 쿠키런 서버 Re-architecting 사례 (Gaming on AWS)AWS와 함께 한 쿠키런 서버 Re-architecting 사례 (Gaming on AWS)
AWS와 함께 한 쿠키런 서버 Re-architecting 사례 (Gaming on AWS)
 
TOGAF 9 Architectural Artifacts
TOGAF 9  Architectural ArtifactsTOGAF 9  Architectural Artifacts
TOGAF 9 Architectural Artifacts
 
DDD patterns that were not in the book
DDD patterns that were not in the bookDDD patterns that were not in the book
DDD patterns that were not in the book
 
Gestión de Cambios de BBDD con LiquiBase
Gestión de Cambios de BBDD con LiquiBaseGestión de Cambios de BBDD con LiquiBase
Gestión de Cambios de BBDD con LiquiBase
 
The Acord Framework - An Insurance Enterprise Architecture (2011).pdf
The Acord Framework - An Insurance Enterprise Architecture (2011).pdfThe Acord Framework - An Insurance Enterprise Architecture (2011).pdf
The Acord Framework - An Insurance Enterprise Architecture (2011).pdf
 
The Ultimate Logging Architecture - You KNOW you want it!
The Ultimate Logging Architecture - You KNOW you want it!The Ultimate Logging Architecture - You KNOW you want it!
The Ultimate Logging Architecture - You KNOW you want it!
 
Togaf 9.2 Introduction
Togaf 9.2 IntroductionTogaf 9.2 Introduction
Togaf 9.2 Introduction
 
GraphQL as an alternative approach to REST (as presented at Java2Days/CodeMon...
GraphQL as an alternative approach to REST (as presented at Java2Days/CodeMon...GraphQL as an alternative approach to REST (as presented at Java2Days/CodeMon...
GraphQL as an alternative approach to REST (as presented at Java2Days/CodeMon...
 
Understanding and Applying The Open Group Architecture Framework (TOGAF)
Understanding and Applying The Open Group Architecture Framework (TOGAF)Understanding and Applying The Open Group Architecture Framework (TOGAF)
Understanding and Applying The Open Group Architecture Framework (TOGAF)
 
[Atlassian in 부산]Git을 이용한 형상관리 전략_투씨드
[Atlassian in 부산]Git을 이용한 형상관리 전략_투씨드[Atlassian in 부산]Git을 이용한 형상관리 전략_투씨드
[Atlassian in 부산]Git을 이용한 형상관리 전략_투씨드
 
Software Architecture: views and viewpoints
Software Architecture: views and viewpointsSoftware Architecture: views and viewpoints
Software Architecture: views and viewpoints
 
Doors hints and tips schema
Doors hints and tips schemaDoors hints and tips schema
Doors hints and tips schema
 
Enterprise Architecture Toolkit Overview
Enterprise Architecture Toolkit OverviewEnterprise Architecture Toolkit Overview
Enterprise Architecture Toolkit Overview
 
Software architecture document
Software architecture documentSoftware architecture document
Software architecture document
 
A pattern language for microservices - June 2021
A pattern language for microservices - June 2021 A pattern language for microservices - June 2021
A pattern language for microservices - June 2021
 
Jira + Confluence + Bitbucket으로 이슈 트래킹 걸음마 떼기
Jira + Confluence + Bitbucket으로 이슈 트래킹 걸음마 떼기Jira + Confluence + Bitbucket으로 이슈 트래킹 걸음마 떼기
Jira + Confluence + Bitbucket으로 이슈 트래킹 걸음마 떼기
 

Similar to Demystifying Drupal AJAX Callback Commands

NYCCAMP 2015 Demystifying Drupal AJAX Callback Commands
NYCCAMP 2015 Demystifying Drupal AJAX Callback CommandsNYCCAMP 2015 Demystifying Drupal AJAX Callback Commands
NYCCAMP 2015 Demystifying Drupal AJAX Callback Commands
Michael Miles
 
Анатолий Поляков - Drupal.ajax framework from a to z
Анатолий Поляков - Drupal.ajax framework from a to zАнатолий Поляков - Drupal.ajax framework from a to z
Анатолий Поляков - Drupal.ajax framework from a to z
LEDC 2016
 
Drupal8Day: Demystifying Drupal 8 Ajax Callback commands
Drupal8Day: Demystifying Drupal 8 Ajax Callback commandsDrupal8Day: Demystifying Drupal 8 Ajax Callback commands
Drupal8Day: Demystifying Drupal 8 Ajax Callback commands
Michael Miles
 
Demystifying AJAX Callback Commands in Drupal 8
Demystifying AJAX Callback Commands in Drupal 8Demystifying AJAX Callback Commands in Drupal 8
Demystifying AJAX Callback Commands in Drupal 8
Michael Miles
 
How to Create and Load Model in Laravel
How to Create and Load Model in LaravelHow to Create and Load Model in Laravel
How to Create and Load Model in Laravel
Yogesh singh
 
Ajax on drupal the right way - DrupalCamp Campinas, São Paulo, Brazil 2016
Ajax on drupal the right way - DrupalCamp Campinas, São Paulo, Brazil 2016Ajax on drupal the right way - DrupalCamp Campinas, São Paulo, Brazil 2016
Ajax on drupal the right way - DrupalCamp Campinas, São Paulo, Brazil 2016
Nicolás Bouhid
 
MidCamp 2016 - Demystifying AJAX Callback Commands in Drupal 8
MidCamp 2016 - Demystifying AJAX Callback Commands in Drupal 8MidCamp 2016 - Demystifying AJAX Callback Commands in Drupal 8
MidCamp 2016 - Demystifying AJAX Callback Commands in Drupal 8
Michael Miles
 
jQuery and Rails: Best Friends Forever
jQuery and Rails: Best Friends ForeverjQuery and Rails: Best Friends Forever
jQuery and Rails: Best Friends Forever
stephskardal
 
Drupal & javascript
Drupal & javascriptDrupal & javascript
Drupal & javascript
Almog Baku
 
PHP MVC
PHP MVCPHP MVC
The state of hooking into Drupal - DrupalCon Dublin
The state of hooking into Drupal - DrupalCon DublinThe state of hooking into Drupal - DrupalCon Dublin
The state of hooking into Drupal - DrupalCon Dublin
Nida Ismail Shah
 
Modular javascript
Modular javascriptModular javascript
Modular javascript
Zain Shaikh
 
Laravel 8 export data as excel file with example
Laravel 8 export data as excel file with exampleLaravel 8 export data as excel file with example
Laravel 8 export data as excel file with example
Katy Slemon
 
PHP and Mysql
PHP and MysqlPHP and Mysql
PHP and Mysql
Sankhadeep Roy
 
Using php with my sql
Using php with my sqlUsing php with my sql
Using php with my sql
salissal
 
Drupal 7 Theming - Behind the scenes
Drupal 7 Theming - Behind the scenes Drupal 7 Theming - Behind the scenes
Drupal 7 Theming - Behind the scenes
ramakesavan
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
Jonathan Wage
 
Power shell examples_v4
Power shell examples_v4Power shell examples_v4
Power shell examples_v4
JoeDinaso
 
Writing HTML5 Web Apps using Backbone.js and GAE
Writing HTML5 Web Apps using Backbone.js and GAEWriting HTML5 Web Apps using Backbone.js and GAE
Writing HTML5 Web Apps using Backbone.js and GAE
Ron Reiter
 
8 things to know about theming in drupal 8
8 things to know about theming in drupal 88 things to know about theming in drupal 8
8 things to know about theming in drupal 8
Logan Farr
 

Similar to Demystifying Drupal AJAX Callback Commands (20)

NYCCAMP 2015 Demystifying Drupal AJAX Callback Commands
NYCCAMP 2015 Demystifying Drupal AJAX Callback CommandsNYCCAMP 2015 Demystifying Drupal AJAX Callback Commands
NYCCAMP 2015 Demystifying Drupal AJAX Callback Commands
 
Анатолий Поляков - Drupal.ajax framework from a to z
Анатолий Поляков - Drupal.ajax framework from a to zАнатолий Поляков - Drupal.ajax framework from a to z
Анатолий Поляков - Drupal.ajax framework from a to z
 
Drupal8Day: Demystifying Drupal 8 Ajax Callback commands
Drupal8Day: Demystifying Drupal 8 Ajax Callback commandsDrupal8Day: Demystifying Drupal 8 Ajax Callback commands
Drupal8Day: Demystifying Drupal 8 Ajax Callback commands
 
Demystifying AJAX Callback Commands in Drupal 8
Demystifying AJAX Callback Commands in Drupal 8Demystifying AJAX Callback Commands in Drupal 8
Demystifying AJAX Callback Commands in Drupal 8
 
How to Create and Load Model in Laravel
How to Create and Load Model in LaravelHow to Create and Load Model in Laravel
How to Create and Load Model in Laravel
 
Ajax on drupal the right way - DrupalCamp Campinas, São Paulo, Brazil 2016
Ajax on drupal the right way - DrupalCamp Campinas, São Paulo, Brazil 2016Ajax on drupal the right way - DrupalCamp Campinas, São Paulo, Brazil 2016
Ajax on drupal the right way - DrupalCamp Campinas, São Paulo, Brazil 2016
 
MidCamp 2016 - Demystifying AJAX Callback Commands in Drupal 8
MidCamp 2016 - Demystifying AJAX Callback Commands in Drupal 8MidCamp 2016 - Demystifying AJAX Callback Commands in Drupal 8
MidCamp 2016 - Demystifying AJAX Callback Commands in Drupal 8
 
jQuery and Rails: Best Friends Forever
jQuery and Rails: Best Friends ForeverjQuery and Rails: Best Friends Forever
jQuery and Rails: Best Friends Forever
 
Drupal & javascript
Drupal & javascriptDrupal & javascript
Drupal & javascript
 
PHP MVC
PHP MVCPHP MVC
PHP MVC
 
The state of hooking into Drupal - DrupalCon Dublin
The state of hooking into Drupal - DrupalCon DublinThe state of hooking into Drupal - DrupalCon Dublin
The state of hooking into Drupal - DrupalCon Dublin
 
Modular javascript
Modular javascriptModular javascript
Modular javascript
 
Laravel 8 export data as excel file with example
Laravel 8 export data as excel file with exampleLaravel 8 export data as excel file with example
Laravel 8 export data as excel file with example
 
PHP and Mysql
PHP and MysqlPHP and Mysql
PHP and Mysql
 
Using php with my sql
Using php with my sqlUsing php with my sql
Using php with my sql
 
Drupal 7 Theming - Behind the scenes
Drupal 7 Theming - Behind the scenes Drupal 7 Theming - Behind the scenes
Drupal 7 Theming - Behind the scenes
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
Power shell examples_v4
Power shell examples_v4Power shell examples_v4
Power shell examples_v4
 
Writing HTML5 Web Apps using Backbone.js and GAE
Writing HTML5 Web Apps using Backbone.js and GAEWriting HTML5 Web Apps using Backbone.js and GAE
Writing HTML5 Web Apps using Backbone.js and GAE
 
8 things to know about theming in drupal 8
8 things to know about theming in drupal 88 things to know about theming in drupal 8
8 things to know about theming in drupal 8
 

More from Michael Miles

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

More from Michael Miles (17)

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

Recently uploaded

Gen Z and the marketplaces - let's translate their needs
Gen Z and the marketplaces - let's translate their needsGen Z and the marketplaces - let's translate their needs
Gen Z and the marketplaces - let's translate their needs
Laura Szabó
 
Discover the benefits of outsourcing SEO to India
Discover the benefits of outsourcing SEO to IndiaDiscover the benefits of outsourcing SEO to India
Discover the benefits of outsourcing SEO to India
davidjhones387
 
7 Best Cloud Hosting Services to Try Out in 2024
7 Best Cloud Hosting Services to Try Out in 20247 Best Cloud Hosting Services to Try Out in 2024
7 Best Cloud Hosting Services to Try Out in 2024
Danica Gill
 
不能毕业如何获得(USYD毕业证)悉尼大学毕业证成绩单一比一原版制作
不能毕业如何获得(USYD毕业证)悉尼大学毕业证成绩单一比一原版制作不能毕业如何获得(USYD毕业证)悉尼大学毕业证成绩单一比一原版制作
不能毕业如何获得(USYD毕业证)悉尼大学毕业证成绩单一比一原版制作
bseovas
 
Should Repositories Participate in the Fediverse?
Should Repositories Participate in the Fediverse?Should Repositories Participate in the Fediverse?
Should Repositories Participate in the Fediverse?
Paul Walk
 
Search Result Showing My Post is Now Buried
Search Result Showing My Post is Now BuriedSearch Result Showing My Post is Now Buried
Search Result Showing My Post is Now Buried
Trish Parr
 
Azure EA Sponsorship - Customer Guide.pdf
Azure EA Sponsorship - Customer Guide.pdfAzure EA Sponsorship - Customer Guide.pdf
Azure EA Sponsorship - Customer Guide.pdf
AanSulistiyo
 
存档可查的(USC毕业证)南加利福尼亚大学毕业证成绩单制做办理
存档可查的(USC毕业证)南加利福尼亚大学毕业证成绩单制做办理存档可查的(USC毕业证)南加利福尼亚大学毕业证成绩单制做办理
存档可查的(USC毕业证)南加利福尼亚大学毕业证成绩单制做办理
fovkoyb
 
留学学历(UoA毕业证)奥克兰大学毕业证成绩单官方原版办理
留学学历(UoA毕业证)奥克兰大学毕业证成绩单官方原版办理留学学历(UoA毕业证)奥克兰大学毕业证成绩单官方原版办理
留学学历(UoA毕业证)奥克兰大学毕业证成绩单官方原版办理
bseovas
 
学位认证网(DU毕业证)迪肯大学毕业证成绩单一比一原版制作
学位认证网(DU毕业证)迪肯大学毕业证成绩单一比一原版制作学位认证网(DU毕业证)迪肯大学毕业证成绩单一比一原版制作
学位认证网(DU毕业证)迪肯大学毕业证成绩单一比一原版制作
zyfovom
 
一比一原版(USYD毕业证)悉尼大学毕业证如何办理
一比一原版(USYD毕业证)悉尼大学毕业证如何办理一比一原版(USYD毕业证)悉尼大学毕业证如何办理
一比一原版(USYD毕业证)悉尼大学毕业证如何办理
k4ncd0z
 
制作原版1:1(Monash毕业证)莫纳什大学毕业证成绩单办理假
制作原版1:1(Monash毕业证)莫纳什大学毕业证成绩单办理假制作原版1:1(Monash毕业证)莫纳什大学毕业证成绩单办理假
制作原版1:1(Monash毕业证)莫纳什大学毕业证成绩单办理假
ukwwuq
 
重新申请毕业证书(RMIT毕业证)皇家墨尔本理工大学毕业证成绩单精仿办理
重新申请毕业证书(RMIT毕业证)皇家墨尔本理工大学毕业证成绩单精仿办理重新申请毕业证书(RMIT毕业证)皇家墨尔本理工大学毕业证成绩单精仿办理
重新申请毕业证书(RMIT毕业证)皇家墨尔本理工大学毕业证成绩单精仿办理
vmemo1
 
假文凭国外(Adelaide毕业证)澳大利亚国立大学毕业证成绩单办理
假文凭国外(Adelaide毕业证)澳大利亚国立大学毕业证成绩单办理假文凭国外(Adelaide毕业证)澳大利亚国立大学毕业证成绩单办理
假文凭国外(Adelaide毕业证)澳大利亚国立大学毕业证成绩单办理
cuobya
 
办理毕业证(UPenn毕业证)宾夕法尼亚大学毕业证成绩单快速办理
办理毕业证(UPenn毕业证)宾夕法尼亚大学毕业证成绩单快速办理办理毕业证(UPenn毕业证)宾夕法尼亚大学毕业证成绩单快速办理
办理毕业证(UPenn毕业证)宾夕法尼亚大学毕业证成绩单快速办理
uehowe
 
成绩单ps(UST毕业证)圣托马斯大学毕业证成绩单快速办理
成绩单ps(UST毕业证)圣托马斯大学毕业证成绩单快速办理成绩单ps(UST毕业证)圣托马斯大学毕业证成绩单快速办理
成绩单ps(UST毕业证)圣托马斯大学毕业证成绩单快速办理
ysasp1
 
制作毕业证书(ANU毕业证)莫纳什大学毕业证成绩单官方原版办理
制作毕业证书(ANU毕业证)莫纳什大学毕业证成绩单官方原版办理制作毕业证书(ANU毕业证)莫纳什大学毕业证成绩单官方原版办理
制作毕业证书(ANU毕业证)莫纳什大学毕业证成绩单官方原版办理
cuobya
 
HijackLoader Evolution: Interactive Process Hollowing
HijackLoader Evolution: Interactive Process HollowingHijackLoader Evolution: Interactive Process Hollowing
HijackLoader Evolution: Interactive Process Hollowing
Donato Onofri
 
办理毕业证(NYU毕业证)纽约大学毕业证成绩单官方原版办理
办理毕业证(NYU毕业证)纽约大学毕业证成绩单官方原版办理办理毕业证(NYU毕业证)纽约大学毕业证成绩单官方原版办理
办理毕业证(NYU毕业证)纽约大学毕业证成绩单官方原版办理
uehowe
 
Design Thinking NETFLIX using all techniques.pptx
Design Thinking NETFLIX using all techniques.pptxDesign Thinking NETFLIX using all techniques.pptx
Design Thinking NETFLIX using all techniques.pptx
saathvikreddy2003
 

Recently uploaded (20)

Gen Z and the marketplaces - let's translate their needs
Gen Z and the marketplaces - let's translate their needsGen Z and the marketplaces - let's translate their needs
Gen Z and the marketplaces - let's translate their needs
 
Discover the benefits of outsourcing SEO to India
Discover the benefits of outsourcing SEO to IndiaDiscover the benefits of outsourcing SEO to India
Discover the benefits of outsourcing SEO to India
 
7 Best Cloud Hosting Services to Try Out in 2024
7 Best Cloud Hosting Services to Try Out in 20247 Best Cloud Hosting Services to Try Out in 2024
7 Best Cloud Hosting Services to Try Out in 2024
 
不能毕业如何获得(USYD毕业证)悉尼大学毕业证成绩单一比一原版制作
不能毕业如何获得(USYD毕业证)悉尼大学毕业证成绩单一比一原版制作不能毕业如何获得(USYD毕业证)悉尼大学毕业证成绩单一比一原版制作
不能毕业如何获得(USYD毕业证)悉尼大学毕业证成绩单一比一原版制作
 
Should Repositories Participate in the Fediverse?
Should Repositories Participate in the Fediverse?Should Repositories Participate in the Fediverse?
Should Repositories Participate in the Fediverse?
 
Search Result Showing My Post is Now Buried
Search Result Showing My Post is Now BuriedSearch Result Showing My Post is Now Buried
Search Result Showing My Post is Now Buried
 
Azure EA Sponsorship - Customer Guide.pdf
Azure EA Sponsorship - Customer Guide.pdfAzure EA Sponsorship - Customer Guide.pdf
Azure EA Sponsorship - Customer Guide.pdf
 
存档可查的(USC毕业证)南加利福尼亚大学毕业证成绩单制做办理
存档可查的(USC毕业证)南加利福尼亚大学毕业证成绩单制做办理存档可查的(USC毕业证)南加利福尼亚大学毕业证成绩单制做办理
存档可查的(USC毕业证)南加利福尼亚大学毕业证成绩单制做办理
 
留学学历(UoA毕业证)奥克兰大学毕业证成绩单官方原版办理
留学学历(UoA毕业证)奥克兰大学毕业证成绩单官方原版办理留学学历(UoA毕业证)奥克兰大学毕业证成绩单官方原版办理
留学学历(UoA毕业证)奥克兰大学毕业证成绩单官方原版办理
 
学位认证网(DU毕业证)迪肯大学毕业证成绩单一比一原版制作
学位认证网(DU毕业证)迪肯大学毕业证成绩单一比一原版制作学位认证网(DU毕业证)迪肯大学毕业证成绩单一比一原版制作
学位认证网(DU毕业证)迪肯大学毕业证成绩单一比一原版制作
 
一比一原版(USYD毕业证)悉尼大学毕业证如何办理
一比一原版(USYD毕业证)悉尼大学毕业证如何办理一比一原版(USYD毕业证)悉尼大学毕业证如何办理
一比一原版(USYD毕业证)悉尼大学毕业证如何办理
 
制作原版1:1(Monash毕业证)莫纳什大学毕业证成绩单办理假
制作原版1:1(Monash毕业证)莫纳什大学毕业证成绩单办理假制作原版1:1(Monash毕业证)莫纳什大学毕业证成绩单办理假
制作原版1:1(Monash毕业证)莫纳什大学毕业证成绩单办理假
 
重新申请毕业证书(RMIT毕业证)皇家墨尔本理工大学毕业证成绩单精仿办理
重新申请毕业证书(RMIT毕业证)皇家墨尔本理工大学毕业证成绩单精仿办理重新申请毕业证书(RMIT毕业证)皇家墨尔本理工大学毕业证成绩单精仿办理
重新申请毕业证书(RMIT毕业证)皇家墨尔本理工大学毕业证成绩单精仿办理
 
假文凭国外(Adelaide毕业证)澳大利亚国立大学毕业证成绩单办理
假文凭国外(Adelaide毕业证)澳大利亚国立大学毕业证成绩单办理假文凭国外(Adelaide毕业证)澳大利亚国立大学毕业证成绩单办理
假文凭国外(Adelaide毕业证)澳大利亚国立大学毕业证成绩单办理
 
办理毕业证(UPenn毕业证)宾夕法尼亚大学毕业证成绩单快速办理
办理毕业证(UPenn毕业证)宾夕法尼亚大学毕业证成绩单快速办理办理毕业证(UPenn毕业证)宾夕法尼亚大学毕业证成绩单快速办理
办理毕业证(UPenn毕业证)宾夕法尼亚大学毕业证成绩单快速办理
 
成绩单ps(UST毕业证)圣托马斯大学毕业证成绩单快速办理
成绩单ps(UST毕业证)圣托马斯大学毕业证成绩单快速办理成绩单ps(UST毕业证)圣托马斯大学毕业证成绩单快速办理
成绩单ps(UST毕业证)圣托马斯大学毕业证成绩单快速办理
 
制作毕业证书(ANU毕业证)莫纳什大学毕业证成绩单官方原版办理
制作毕业证书(ANU毕业证)莫纳什大学毕业证成绩单官方原版办理制作毕业证书(ANU毕业证)莫纳什大学毕业证成绩单官方原版办理
制作毕业证书(ANU毕业证)莫纳什大学毕业证成绩单官方原版办理
 
HijackLoader Evolution: Interactive Process Hollowing
HijackLoader Evolution: Interactive Process HollowingHijackLoader Evolution: Interactive Process Hollowing
HijackLoader Evolution: Interactive Process Hollowing
 
办理毕业证(NYU毕业证)纽约大学毕业证成绩单官方原版办理
办理毕业证(NYU毕业证)纽约大学毕业证成绩单官方原版办理办理毕业证(NYU毕业证)纽约大学毕业证成绩单官方原版办理
办理毕业证(NYU毕业证)纽约大学毕业证成绩单官方原版办理
 
Design Thinking NETFLIX using all techniques.pptx
Design Thinking NETFLIX using all techniques.pptxDesign Thinking NETFLIX using all techniques.pptx
Design Thinking NETFLIX using all techniques.pptx
 

Demystifying Drupal AJAX Callback Commands

  • 1. Demystifying Drupal AJAX Callback Commands http://nerdsummit.org/node/2068 NERDsummit 2015 #NERDsummit
  • 2. Goals of this Session Explain what AJAX callback commands are Demonstrate how to use AJAX callback commands Outline how to create AJAX callback commands
  • 4. Warning About Example Code There is example code Some coding standards ignored for presentation purposes Drupal 8 code still subject to change
  • 6. From a High Level The response of AJAX request PHP code to instruct JavaScript functions A JavaScript function attached to an object Defined by Drupal core or modules 17 AJAX callback commands in Drupal 7
  • 7. Example: The "Remove" Command Using the "examples" module (available on Drupal.org), showing using the 'remove' AJAX Callback command. The checkbox is checked, which makes an AJAX request, which returns the command to remove the element with the sample text.
  • 8. On the Client Side [D7] A function on the 'Drupal.ajax.prototype.commands' object Receives 'ajax', 'response' and 'status' arguments A wrapper for additional javascript // Provide a series of commands that the server can request the client perform. Drupal.ajax.prototype.commands = { //... /** * Command to remove a chunk from the page. */ remove: function (ajax, response, status) { var settings = response.settings || ajax.settings || Drupal.settings; Drupal.detachBehaviors($(response.selector), settings); $(response.selector).remove(); }, //... } misc/ajax.js
  • 9. On the Server Side [D7] A PHP function which returns an associative array Array must have an element with key of 'command' The value is the name of a JavaScript function Additional array elements set as response data /** * Creates a Drupal Ajax 'remove' command. */ function ajax_command_remove($selector) { return array( 'command' => 'remove', 'selector' => $selector, ); } includes/ajax.inc
  • 10.
  • 11. How to Use Commands
  • 12. Example Scenario  As a user When I navigate to the 'my-messages' page Then I see a list of my unread messages And I see a list of my read messages When I click on an unread message Then the full messaged is retrieved from the server And I see the content of my message And the message is removed from the unread messages list And the message is added to the read messages list
  • 14. To Use Commands... 1.  Include Drupal AJAX JavaScript library 2.  Attach AJAX to page elements 3.  Define a callback path and function Returns a render array of commands [D7]
  • 15. 1. Include Drupal AJAX library // Render a page of messages. function mymodule_messages_page() { // Include AJAX library. drupal_add_library('system', 'drupal.ajax'); // Create inital page content. $content = theme_item_list(array( 'title' => t('Unread Messages'), 'type' => 'ul', 'attributes' => array( 'id' => 'unread-msgs'), 'items' => mymodule_messages_list(mymodule_get_unread_messages()), )); $content .= '<div id="current-msg"><h2></h2><p></p></div>'; $content .= theme_item_list(array( 'title' => t('Read Messages'), 'type' => 'ul', 'attributes' => array('id' => 'read-msgs'), 'items' => mymodule_messages_list(mymodule_get_read_messages(), FALSE), )); return $content; } mymodule/mymodule.module Function to build a page of messages. On line #4, using the drupal_add_librry() function to include the AJAX library on the page.
  • 16. 2. Attach AJAX to page elements // Return array of message titles for use in a list. function mymodule_messages_list($messages, $display_link = TRUE) { $list_items = array(); foreach ($messages as $mid => $msg) { // Build link to AJAX callback to load message. $link = l($msg->subject, 'read-message-callback/nojs/' . $mid, array( // Add class to link so Drupal knows to use AJAX. 'attributes' => array('class' => array('use-ajax')), )); // Create list item for message. $list_items[] = array( 'id' => 'msg-' . $mid, // Set data to read message link or just message subject. 'data' => $display_link ? $link : $msg->subject, ); } return $list_items; } mymodule/mymodule.module Function to build a list of messages. On line #6, creating a link element which links to our callback path. On line #8, adding the class 'use­ajax' so AJAX framework knows to serve link with an AJAX request.
  • 17. 3.a Define a callback path // Implements hook_menu(). function mymodule_menu() { $items = array(); //.. Other menu items. // None JS callback, for graceful degredation. $items['read-message-callback/nojs/%'] = array( 'title' => 'AJAX Callback to Read Message', 'access arguments' => array('access content'), 'page callback' => 'mymodule_read_message_callback', 'page arguments' => array(1,2), 'type' => MENU_CALLBACK, ); // Create AJAX callback. Add ajax_delivery callback. $items['read-message-callback/ajax/%'] = array( 'delivery callback' => 'ajax_deliver', ) + $items['read-message-callback/nojs/%']; return $items; } mymodule/mymodule.module Creating two menu items for callback functions. The first is for handling graceful degredation when reached outside an AJAX Request. The second is the AJAX callback, which add a delivery callback of "ajax_callback" so Drupal know to return an AJAX Response object.
  • 18. 3.b Return array of commands using a render array [D7] // AJAX Callback to read a message. function mymodule_read_message_callback($method, $mid) { $message = mymodule_load_message($mid); // @TODO: Graceful degredation if not from ajax method or if no message. $commands = array( // Replace content of current message subject. ajax_command_html('#current-msg h2', $message->subject), // Replace content of current message body. ajax_command_html('#current-msg p', $message->content), // Remove message from unread list. ajax_command_remove('#msg-' . $mid), // Add message to read list ajax_command_append('#read-msgs', '<li>' . $message->subject . '</li>'), ); // Return an AJAX render array. return array( '#type' => 'ajax', '#commands' => $commands, ); } mymodule/mymodule.module Lines #5 thru #14, building an array of Core AJAX Callback commands. Each mapps to a javascript function. Line #16 building a render array of type 'ajax'. Drupal will package into JSON and send back to the client.
  • 19.
  • 21. To Create a Command... 1.  Add a function to the Drupal ajax command JavaScript object 2.  Write PHP code that returns an associative array. Must have an element with key of 'command' Value is name of the JavaScript function Additional elements for response data
  • 23. A Custom Command in Drupal 7 1.  Add a function to 'Drupal.ajax.prototype.commands' 2.  Define a PHP function to return an array
  • 24. 1. Add a function to 'Drupal.ajax.prototype.commands' (function($, Drupal) { // Add new command for reading a message. Drupal.ajax.prototype.commands.readMessage = function(ajax, response, status){ // Place content in current-msg div. $('#current-msg h2').html(response.subject); $('#current-msg p').html(response.content); // Remove from unread list. $('#msg-' + response.mid).remove(); // Add message to read list. $('#read-msgs').append('<li>' + response.subject + '</li>'); } })(jQuery, Drupal); mymodule/js/commands.js Attach a new 'readMessage' command to the Drupal AJAX Commands JavaScript object. Function takes in the 3 arguments "ajax", "response" & "status". Wraps jQuery functions to display a message on the page.
  • 25. 2. Define a PHP function to return an associative array /** * AJAX command to read a message. */ function mymodule_command_read_message($message) { return array( 'command' => 'readMessage', 'mid' => $message->mid, 'subject' => $message->subject, 'content' => $message->content, ); } mymodule/mymodule.module PHP function that mapps to the new JavaScript 'readMessage' array. Returns an associative array, with an element that has a key of 'command' and value of the JavaScript function name 'readMessage'. Then additional elements to be sent as request data.
  • 26. Using a custom command... 1.  Tell Drupal to include custom JavaScript 2.  Return custom command in callback function
  • 28. Using a Custom Command in Drupal 7 1.  Use drupal_add_js() to include custom JavaScript on page 2.  Add command to render array returned by callback
  • 29. 1. Use drupal_add_js() to include custom JavaScript on page // Render a page of my messages function mymodule_messages_page() { // Include AJAX library. drupal_add_library('system', 'drupal.ajax'); // Include custom JavaScript. drupal_add_js(drupal_get_path('module', 'mymodule') . '/js/commands.js'); // .. Build $content. return $content; } mymodule/mymodule.module The example function for creating the messages page. In addition to adding the Drupal AJAX library on line #4 also using drupal_add_js() to include custom javascript file on line #6.
  • 30. 2. Add command to render array returned by callback // AJAX Callback to read a message. function mymodule_read_message_callback($method, $mid) { $message = mymodule_load_message($mid); // @TODO: Graceful degredation if not from ajax method or if no message. $commands = array( // Call the readMessage javascript function. mymodule_command_read_message($message), ); // Return an AJAX render array. return array( '#type' => 'ajax', '#commands' => $commands, ); } mymodule/mymodule.module The example callback function that returns an AJAX render array. Commands array on lines #5 thru #8, only returns a single command. The new custom command that was created.
  • 31.
  • 32. AJAX Commands in Drupal 8
  • 33. Changes to AJAX Commands 22 AJAX callback commands in Drupal 8 JavaScript attatches to 'Drupal.AjaxCommands.prototype' object A PHP object that implements CommandInterface Must implement 'render' method
  • 34. Example: The "Remove" Command Using the "examples" module (available on Drupal.org), showing using the 'remove' AJAX Callback command. The checkbox is checked, which makes an AJAX request, which returns the command to remove the element with the sample text.
  • 35. A function on the 'Drupal.AjaxCommands.prototype' object /** * Provide a series of commands that the client will perform. */ Drupal.AjaxCommands.prototype = { //... /** * Command to remove a chunk from the page. */ remove: function (ajax, response, status) { var settings = response.settings || ajax.settings || drupalSettings; $(response.selector).each(function () { Drupal.detachBehaviors(this, settings); }).remove(); }, //... } misc/ajax.js
  • 36. An object that implements CommandInterface Must implement 'render' method namespace DrupalCoreAjax; use DrupalCoreAjaxCommandInterface; // AJAX command for calling the jQuery remove() method. class RemoveCommand Implements CommandInterface { protected $selector; // Constructs a RemoveCommand object. public function __construct($selector) { $this->selector = $selector; } // Implements DrupalCoreAjaxCommandInterface:render(). public function render() { return array( 'command' => 'remove', 'selector' => $this->selector, ); } } core/lib/Drupal/Core/Ajax/RemoveCommand.php
  • 37. To Use Commands in Drupal 8 1.  Include Drupal AJAX JavaScript library Must attach to a render array 2.  Attach AJAX to page elements 3.  Define a callback path and function Returns an AjaxResponse object
  • 39. Attach library to a render array namespace DrupalmymoduleController; use DrupalCoreControllerControllerBase; class MyModuleController extends ControllerBase { // ... // Render a page of my messages public function messagesPage() { // ... build $content // Create render array. $page[] = array( '#type' => 'markup', '#markup' => $content, ); // Attach JavaScript library. $page['#attached']['library'][] = 'core/drupal.ajax'; return $page; } // ... } mymodule/src/Controller/MyModuleController.php Function for building messages page is now using a render array. to the '#attached', 'library' array of that render array, declaring the drupal.ajax library to be included.
  • 40. Callback returns commands using an AJAXResponse() [D8] namespace DrupalmymoduleController; use DrupalCoreControllerControllerBase; class MyModuleController extends ControllerBase { // ... // AJAX Callback to read a message. public function readMessageCallback($method, $mid) { $msg = mymodule_load_message($mid); // Create AJAX Response object. $response = new AjaxResponse(); // Replace content of current message subject. $response->addCommand(new HtmlCommand('#current-msg h2', $msg->subject)); // Replace content of current message body. $response->addCommand(new HtmlCommand('#current-msg p', $msg->content)); // Remove message from unread list. $response->addCommand(new RemoveCommand('#msg-' . $mid)); // Add message to read list. $item = '<li>' . $msg->subject . '</li>'; $response->addCommand(new AppendCommand('#read-msgs', $item)); // Return ajax response. return $response; } mymodule/src/Controller/MyModuleController.php Returning an AjaxResponse object instead of a render array like in Drupal 7. AjaxResponse has an 'addCommand' method, which takes the argument of a command object.
  • 41. Custom Commands in Drupal 8 1.  Add function to 'Drupal.AjaxCommands.prototype' 2.  Define a command object that implements CommandInterface
  • 42. 1. Add function to 'Drupal.AjaxCommands.prototype' (function($, Drupal) { /** * Add new command for reading a message. */ Drupal.AjaxCommands.prototype.readMessage = function(ajax, response, status){ // Place content in current-msg div. $('#current-msg h2').html(response.subject); $('#current-msg p').html(response.content); // Remove from unread list. $('#msg-' + response.mid).remove(); // Add message to read list. $('#read-msgs').append('<li>' + response.subject + '</li>'); } })(jQuery, Drupal); mymodule/js/commands.js Adding the custom 'readMessage' function to the Drupal 8 JavaScript AJAX Commands object. Still takes the same three arguments as in Drupal 7.
  • 43. 2. Define command object that implements CommandInterface namespace DrupalmymoduleAjax; use DrupalCoreAjaxCommandInterface; class ReadMessageCommand implements CommandInterface { protected $message; // Constructs a ReadMessageCommand object. public function __construct($message) { $this->message = $message; } // Implements DrupalCoreAjaxCommandInterface:render(). public function render() { return array( 'command' => 'readMessage', 'mid' => $this->message->mid, 'subject' => $this->message->subject, 'content' => $this->message->content, ); } } mymodule/src/Ajax/ReadMessageCommand.php Creating a Command object which implements the CommandInterface. Must declare a 'render' method, which will return an associative array. This associative array must have an element with the key of 'command' and value of the JavaScript function to run.
  • 44. Using a Custom Command in Drupal 8 1.  Tell Drupal about custom JavaScript library 2.  Attach library to a render array 3.  Add command to AjaxResponse object in callback
  • 45. 1. Tell Drupal about custom JavaScript library mymodule.commands: version: VERSION js: js/commands.js: {} dependencies: - core/drupal.ajax mymodule/mymodule.libraries.yml Must tell Drupal about custom library with a libraries.yml file. Provide an Asset library name, lists all the js files needed, and any dependencies on other libraries.
  • 46. 2. Attach library to a render array namespace DrupalmymoduleController; use DrupalCoreControllerControllerBase; class MyModuleController extends ControllerBase { // ... // Render a page of my messages public function messagesPage() { // .. build $content // Create render array. $page[] = array( '#type' => 'markup', '#markup' => $content, ); // Attach JavaScript library. $page['#attached']['library'][] = 'mymodule/mymodule.commands'; return $page; } // ... } mymodule/mymodule.module Function for building messages page is now using a render array. to the '#attached', 'library' array of that render array, including the custom library. No longer including the AJAX library, as Drupal will know to include it from the libraries.yml file.
  • 47. 3. Add command to AjaxResponse object in callback namespace DrupalmymoduleController; use DrupalCoreControllerControllerBase; class MyModuleController extends ControllerBase { // ... // AJAX Callback to read a message. public function readMessageCallback($method, $mid) { $msg = mymodule_load_message($mid); // Create AJAX Response object. $response = new AjaxResponse(); // Call the readMessage javascript function. $response->addCommand( new ReadMessageCommand($msg)); ); // Return ajax response. return $response; } //... } mymodule/mymodule.module Returning an AjaxResponse object instead of adding the core commands, just adding the new custom command using the 'addCommand' method.
  • 48.
  • 50. AJAX Callback Commands Are... Returned by all AJAX Framework requests PHP abstraction for JavaScript functions Defined by core and modules
  • 51. To Use AJAX Callback Commands... Include Drupal AJAX JavaScript library Attach AJAX to page elements Have server side callback return array of commands
  • 52. To Create AJAX Callback Commands... Add function to Drupal ajax command JavaScript object. Write PHP code to return associative array with a 'command' key
  • 53. To Use Custom AJAX Callback Commands... Include custom JavaScript Include custom command in callback function
  • 54.