A Good Girl's Guide to Murder (A Good Girl's Guide to Murder, #1)
Ajax on drupal the right way - DrupalCamp Campinas, São Paulo, Brazil 2016
1. AJAX on Drupal the right way
Nicolás Bouhid
Software Architect
CI&T
2. About me
● Born in Buenos Aires, Argentina
● PHP developer since 2008
● Drupalist since 2011
● Lives in Brazil since 2013
● Works at
● Drupal contributions:
○ PDF Export
○ Deploy overview views
Linkedin
http://linkedin.com/in/nicolasbouhid/en
D.o. profile
https://www.drupal.org/u/nbouhid
3. Agenda
● What is Ajax API?
● jQuery.ajax vs Ajax API
● How it works?
● Ajax Commands
● Drupal.behaviors
● Form API + Ajax API
● How to use it without a form
● What’s new on Drupal 8?
4. What is Ajax API?
Drupal's Ajax framework is used to dynamically
update parts of a page's HTML based on data
from the server. Upon a specified event, such as a
button click, a callback function is triggered which
performs server-side logic and may return updated
markup, which is then replaced on-the-fly with no page
refresh necessary.
5. What is Ajax API?
This framework creates a PHP macro language
that allows the server to instruct JavaScript to
perform actions on the client browser.
These instructions are called commands.
6. What is Ajax API?
This means…
● ...you can include or reload content on your page...
● …init libraries or execute jQuery functions...
● …you can load CSS/JS libraries exactly when it’s necessary...
… from server side, and everything with almost no custom JS code!
7. jQuery.ajax vs Ajax API
jQuery.ajax is simply a cross browser implementation
to make XMLHttpRequests
Ajax API is built on jQuery and it is a complete framework
designed for Drupal with three main benefits:
● Updates your Drupal.settings object
● Keeps the ids on the DOM unique
● Loads CSS/JS files asynchronously (once!)
That is what makes it so powerful and usually a wise choice
8. How it works?
1. XMLHttpRequest
2.$com
m
ands[]
3.JS
functions
Default Ajax API
Delivery
callback
drupal_deliver_html_page() ajax_deliver()
Ajax
Framework
9. Ajax Commands
They are client side instructions controlled by server side
// $(‘#content’).hide();
$commands[] = ajax_command_invoke('#content', 'hide');
// $(‘#content’).html(‘DrupalCamp’);
$commands[] = ajax_command_html('#content', 'DrupalCamp’);
// $(‘#content’).fadeIn(‘fast’);
$commands[] = ajax_command_invoke('#content', 'fadeIn', array('fast'));
10. Ajax Commands
This means more reusability and covers most of
the important operations that are usually required
on AJAX requests!
Do you not find what you need on the core ajax commands?
Really??? Ok, no problem, you can create your own :)
PSST, wanna see more? Check misc/ajax.js
11. Ajax Commands
All ajax commands are defined in the following JS object
Drupal.ajax.prototype.commands
This means that… you can create your own!
Drupal.ajax.prototype.commands.helloWorld = function (ajax, response, status) {
alert('hello world!');
}
12. Drupal.behaviors
The official Drupal documentation says that every module
that implements JS actions, needs to attach its logic to
Drupal.behaviors:
Drupal.behaviors.exampleModule = {
attach: function (context, settings) {
$('.example', context).click(function () {
$(this).next('ul').toggle('show');
});
}
};
13. Drupal.behaviors
When is it executed?
● $(document).ready()
● After an overlay is opened
● Every time new content is included in the DOM using Ajax API
Views, CTools, Media, Panels, Authcache, and many other modules uses it.
So if you use any of these modules and you can’t make your JS execute at
the right moment, then you should give it a try ;)
15. Let’s take a look at that example code again..
Drupal.behaviors.exampleModule = {
attach: function (context, settings) {
$('.example', context).click(function () {
$(this).next('ul').toggle('show');
});
}
};
Make sure your code runs only when necessary!
Drupal.behaviors
16. Form API + Ajax API
You can use Ajax API combined with Form API
On most cases, it used to reload fields or load new
HTML on the page
Let’s see an example (from ajax_example.module)
17. Form API + Ajax API
/**
* A very basic form which with an AJAX-enabled submit.
*/
function ajax_example_submit_driven_ajax($form, &$form_state) {
$form['box'] = array(
'#type' => 'markup',
'#prefix' => '<div id="box">',
'#suffix' => '</div>',
'#markup' => '<h1>Initial markup for box</h1>',
);
$form['submit'] = array(
'#type' => 'submit',
'#ajax' => array(
'callback' => 'ajax_example_submit_driven_callback',
'wrapper' => 'box',
'effect' => 'none',
'progress' => array('type' => 'throbber'),
),
'#value' => t('Submit'),
);
return $form;
}
18. Form API + Ajax API
/**
* Callback for submit_driven example.
*
* Select the 'box' element, change the markup in it, and return it as a
* renderable array.
*/
function ajax_example_submit_driven_callback($form, $form_state) {
$element = $form['box'];
$element['#markup'] = "Clicked submit ({$form_state['values']['op']}): " . date('c');
return $element;
}
20. Form API + Ajax API
It uses the jQuery Form plugin to make Ajax POST requests
that provides the following events:
● beforeSerialize
Runs before field data is collected.
● beforeSubmit
Modify form values prior to form submission.
● beforeSend
Prepare the Ajax request before it is sent.
● success
● error
21. Form API + Ajax API
You can extend or override events safely!
var defaultBeforeSubmit = Drupal.ajax.prototype.beforeSubmit;
Drupal.ajax['#my-submit'].beforeSubmit = function (form_values, element, options) {
executeMyStuff(form_values, element);
// Remove this line to override the default functionality.
return defaultBeforeSubmit(form_values, element, options);
};
22. How to use it without a form
What happens if I don’t have a form?
Don’t worry, there is a way :)
23. You can use a link
drupal_add_library('system', 'drupal.ajax');
$link = l(t('Click here'), 'my/ajax/url/nojs', array(
'attributes' => array(
'class' => array('use-ajax'),
),
));
And on you page callback of the path my/ajax/url, you just need to:
$output = t("This is some content delivered via AJAX");
$commands = array();
$commands[] = ajax_command_append('#myDiv', $output);
return array(
'#type' => 'ajax',
'#commands' => $commands,
);
How to use it without a form
Remember to set
ajax_deliver as the
delivery callback on
your menu item
definition!
24. How to use it without a form
You can also instantiate your own Drupal.ajax object
var base = $(this).attr('id');
var elementSettings = {
url: settings.basePath + settings.pathPrefix + 'my/ajax/url/nojs',
event: 'click',
progress: {
type: 'throbber'
}
};
Drupal.ajax[base] = new Drupal.ajax(base, this, elementSettings);
$(this).click();
25. What’s new on Drupal 8?
● Commands are built using classes and they may have
assets/dependencies attached to it
● Code cleanup
● Documentation is so much better
● New command: redirect
● More flexibility when passing parameters from server side so it’s
easier to instantiate your plugins!