ajax on drupal the right way - drupalcamp campinas, são paulo, brazil 2016

Post on 07-Apr-2017

29 Views

Category:

Internet

4 Downloads

Preview:

Click to see full reader

TRANSCRIPT

AJAX on Drupal the right way

Nicolás BouhidSoftware ArchitectCI&T

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

Linkedinhttp://linkedin.com/in/nicolasbouhid/en

D.o. profilehttps://www.drupal.org/u/nbouhid

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?

What is Ajax API?

Drupal's Ajax framework is used to dynamicallyupdate parts of a page's HTML based on datafrom 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.

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.

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!

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

How it works?

1. XMLHttpRequest

2. $co

mm

ands[]

3. JS functions

Default Ajax API

Delivery callback

drupal_deliver_html_page() ajax_deliver()Ajax

Framework

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'));

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

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!');}

Drupal.behaviors

The official Drupal documentation says that every modulethat implements JS actions, needs to attach its logic toDrupal.behaviors:

Drupal.behaviors.exampleModule = { attach: function (context, settings) { $('.example', context).click(function () { $(this).next('ul').toggle('show'); }); }};

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 ;)

Drupal.behaviors

But wait… There is a catch!

If you don’t use it properly…

You could have more problems than solutions!

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

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)

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;}

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;}

Form API + Ajax API

$form['submit'] = array( '#type' => 'submit', '#ajax' => array( 'callback' => 'ajax_example_commands_callback', ), '#value' => t('Submit'), );

function ajax_example_commands_callback($form, $form_state) { $commands = array();

$new_string = "Clicked submit ({$form_state['values']['op']}): " . date('c'); $commands[] = ajax_command_replace('#box', $new_string);

$commands[] = ajax_command_alert(t('Updated!'));

return array('#type' => 'ajax', '#commands' => $commands);}

Form API + Ajax API

It uses the jQuery Form plugin to make Ajax POST requests that provides the following events:

● beforeSerializeRuns before field data is collected.

● beforeSubmitModify form values prior to form submission.

● beforeSendPrepare the Ajax request before it is sent.

● success● error

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);};

How to use it without a form

What happens if I don’t have a form?

Don’t worry, there is a way :)

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!

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();

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!

That was it!

top related