Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Drupal Javascript for
developers
Whoami?
• C lin Mariană
• Lead developer @ Dream Production
• calin@dreamproduction.com
• d.o: mariancalinro
• @mariancali...
What will we cover?
• Adding JS to the page, both at module and theme level
• Writing Drupal aware JS code
• Libraries man...
Adding JS to page
• declare it in the .info file of your module
scripts[] = path/to/component.js
• Using drupal_add_js()
d...
Adding JS to page
• declare it in the .info file of your module
scripts[] = path/to/component.js
• Using drupal_add_js()
d...
Adding JS to page
• declare it in the .info file of your module
scripts[] = path/to/component.js
• Using drupal_add_js()
d...
Adding JS to page
• declare it in the .info file of your module
scripts[] = path/to/component.js
• Using drupal_add_js()
d...
Adding JS to page
• for a theme, there are 2 ways to add a JS file to the page:
• declare it in the .info file of your the...
Adding JS to page
• for a theme, there are 2 ways to add a JS file to the page:
• declare it in the .info file of your the...
Adding JS to page
• for a theme, there are 2 ways to add a JS file to the page:
• declare it in the .info file of your the...
Closures
(function ($) {
// Code that uses jQuery's $ can follow here.
$(‘a’).on(‘click’, function(event){
event.preventDe...
Closures
(function ($) {
// Code that uses jQuery's $ can follow here.
$(‘a’).on(‘click’, function(event){
event.preventDe...
Closures
(function ($) {
// Code that uses jQuery's $ can follow here.
$(‘a’).on(‘click’, function(event){
event.preventDe...
Settings
<?php
drupal_add_js(array(
'myModule' => array(
'key' => 'value'
)
), 'setting');
===============================...
Settings
<?php
drupal_add_js(array(
'myModule' => array(
'key' => 'value'
)
), 'setting');
===============================...
Settings
<?php
drupal_add_js(array(
'myModule' => array(
'key' => 'value'
)
), 'setting');
===============================...
Behaviors
• Drupal’s way of dealing with attaching and detaching functionalities
to dynamic content.
• Invoked by Drupal a...
Behaviors
(function($){
Drupal.behaviors.myComponent = {
attach: function(context, settings) {
// Make your DOM manipulati...
Behaviors
(function($){
Drupal.behaviors.myComponent = {
attach: function(context, settings) {
// Make your DOM manipulati...
Behaviors
(function($){
Drupal.behaviors.myComponent = {
attach: function(context, settings) {
// Make your DOM manipulati...
Behaviors
(function($){
Drupal.behaviors.myBxSlider = {
attach: function(context, settings) {
var options = settings.myBxS...
Behaviors
(function($){
Drupal.behaviors.myBxSlider = {
attach: function(context, settings) {
var options = settings.myBxS...
Behaviors
• When adding content to the page, call Drupal.attachBehaviors
on the content. This allows other components to a...
Behaviors
• When adding content to the page, call Drupal.attachBehaviors
on the content. This allows other components to a...
Drupal once
• To protect yourself against having your code run twice on the same
content, Drupal implements a jQuery metho...
Drupal once
(function($){
Drupal.behaviors.myExample = {
attach: function(context, settings) {
$(‘a’, context)
.once(‘noti...
Drupal once
(function($){
Drupal.behaviors.myExample = {
attach: function(context, settings) {
$(‘a’, context)
.once(‘noti...
Drupal once
(function($){
Drupal.behaviors.myExample = {
attach: function(context, settings) {
$(‘a’, context).once(‘notif...
Libraries
• Allows you to add all the JavaScript and CSS of one component at
once
• Example:
drupal_add_library('system', ...
Libraries
• Allows you to add all the JavaScript and CSS of one component at
once
• Example:
drupal_add_library('system', ...
Libraries
• Allows you to add all the JavaScript and CSS of one component at
once
• Example:
drupal_add_library('system', ...
function system_library() {
// ...
$libraries['ui.accordion'] = array(
'title' => 'jQuery UI: Accordion',
'website' => 'ht...
function system_library() {
// ...
$libraries['ui.accordion'] = array(
'title' => 'jQuery UI: Accordion',
'website' => 'ht...
function system_library() {
// ...
$libraries['ui.accordion'] = array(
'title' => 'jQuery UI: Accordion',
'website' => 'ht...
function system_library() {
// ...
$libraries['ui.accordion'] = array(
'title' => 'jQuery UI: Accordion',
'website' => 'ht...
Ajax Framework
• Ajax is a technique that updates content on the page from the server
without page refresh.
• Drupal’s Aja...
Ajax Framework
• ajax_command_insert()
• ajax_command_before()
• ajax_command_after()
• ajax_command_replace()
• ajax_comm...
Ajax Framework
• A php array such as...
array(
'command' => 'insert',
'method' => 'append',
'selector' => '#my-div',
'data...
Ajax Framework
• To implement new command in js:
Drupal.ajax.prototype.commands.myCommand = function
(ajax, response, stat...
Ajax Framework
Example
Ajax Framework
• You print somewhere in the page this link:
array(
'#type' => 'link',
'#title' => t('Ajax Link'),
'#href' ...
Ajax Framework
• You print somewhere in the page this link:
array(
'#type' => 'link',
'#title' => t('Ajax Link'),
'#href' ...
Ajax Framework
• You print somewhere in the page this link:
array(
'#type' => 'link',
'#title' => t('Ajax Link'),
'#href' ...
Ajax Framework
• Alternative way:
array(
'#type' => 'link',
'#title' => t('Ajax Link'),
'#href' => 'my-ajax-test/nojs',
'#...
Ajax Framework
• You need to define a new menu item:
$items['my-ajax-test/%'] = array(
'title' => 'Ajax test callback',
't...
Ajax Framework
• You need to define a new menu item:
$items['my-ajax-test/%'] = array(
'title' => 'Ajax test callback',
't...
Ajax Framework
• Then, define the callback for that menu item:
function ajax_link_callback($ajax) {
$time = t('The current...
Ajax Framework
• Then, define the callback for that menu item:
function ajax_link_callback($ajax) {
$time = t('The current...
Ajax Framework
• Then, define the callback for that menu item:
function ajax_link_callback($ajax) {
$time = t('The current...
Ajax Framework
• Then, define the callback for that menu item:
function ajax_link_callback($ajax) {
$time = t('The current...
Ajax Framework
• Then, define the callback for that menu item:
function ajax_link_callback($ajax) {
$time = t('The current...
Ajax Framework
• Then, define the callback for that menu item:
function ajax_link_callback($ajax) {
$time = t('The current...
Ajax Forms
• Ajax forms in Drupal are provided by the Form API.
• You write the form using the Drupal Form API.
• You do n...
Ajax Forms
• Specifiy what form element activates the Ajax behavior by adding #ajax
to it.
• Specify what part of the form...
Ajax Forms
• Example of FAPI Ajax:
$form['dropdown_first'] = array(
'#type' => 'select',
'#title' => 'Instrument Type',
'#...
Ajax Forms
• Example of FAPI Ajax:
$form['dropdown_first'] = array(
'#type' => 'select',
'#title' => 'Instrument Type',
'#...
Ajax Forms
• Example of FAPI Ajax:
$form['dropdown_second'] = array(
'#type' => 'select',
'#title' => $options_first[$sele...
Ajax Forms
• Example of FAPI Ajax:
$form['dropdown_second'] = array(
'#type' => 'select',
'#title' => $options_first[$sele...
Ajax Forms
• Example of FAPI Ajax:
$form['dropdown_second'] = array(
'#type' => 'select',
'#title' => $options_first[$sele...
Ajax Forms
function dependent_dropdown_callback($form, $form_state) {
return $form['dropdown_second'];
}
Ajax Forms
function dependent_dropdown_callback($form, $form_state) {
return $form['dropdown_second'];
}
States
• Provides interactive forms where the actual underlying form doesn't change,
just the presentation to the user.
• ...
States
$form['source'] = array(
'#type' => 'checkboxes',
'#options' => drupal_map_assoc(array(
t(‘TV'),
t(‘Newspaper’),
t(...
States
$form['source'] = array(
'#type' => 'checkboxes',
'#options' => drupal_map_assoc(array(
t(‘TV'),
t(‘Newspaper’),
t(...
States
$form[‘source_text’] = array(
'#type' => 'textfield',
'#title' => t(‘Write in a few words where you heard of us'),
...
States
$form[‘source_text’] = array(
'#type' => 'textfield',
'#title' => t(‘Write in a few words where you heard of us'),
...
States
$form[‘source_text’] = array(
'#type' => 'textfield',
'#title' => t(‘Write in a few words where you heard of us'),
...
Drupal.theme
• Is the JavaScript counterpart to theme()
• To define a theme function simply create a new public method for...
Drupal.theme
• Is the JavaScript counterpart to theme()
• To define a theme function simply create a new public method for...
Drupal.theme
• Is the JavaScript counterpart to theme()
• To define a theme function simply create a new public method for...
Drupal.theme
• Another developer changes the implementation:
Dupal.theme.prototype.displayName = function(name,
url) {
ret...
Drupal.theme
• Allows you to alter the output of components defined by third parties.
• Allows others to alter the output ...
Multilingual
• Drupal has multilingual support in JS.
• You can wrap your text in Drupal.t(), and it will be available for...
Other API’s
• autocomplete
• FAPI property:
'#autocomplete_path' => ‘some/path’,
• the callback function for that path nee...
Other API’s
• autocomplete
• FAPI property:
'#autocomplete_path' => ‘some/path’,
• the callback function for that path nee...
Other API’s
• autocomplete
• FAPI property:
'#autocomplete_path' => ‘some/path’,
• the callback function for that path nee...
Other API’s
• tabledrag - drupal_add_tabledrag()
• Assists in adding the tableDrag JavaScript behavior to a themed
table
•...
Other API’s - tabledrag
Drupal 8
• Drupal.settings -> drupalSettings
• Drupal.theme.prototype -> Drupal.theme
• Drupal.ajax.prototype.commands ->
...
Drupal 8
• Only the JavaScript required on a particular page will be added to
that page
• jQuery is not automatically load...
Drupal 8 - Defining a library
*.libraries.yml in your module:
cuddly-slider:
version: 1.x
css:
theme:
css/cuddly-slider.cs...
Drupal 8 - Attaching a library
to existing content
<?php
function mymodule_element_info_alter(array &$types) {
if (isset($...
Drupal 8 - Attaching a library
to new content
<?php
$build[‘your_element’]['#attached']['library'][] =
‘mymodule/cuddly-sl...
Drupal 8 - Attaching a library
to pages
hook_page_attachments(). Example from the Contextual links module
<?php
function c...
Drupal 8 - Attaching settings
$build[‘#attached']['drupalSettings']['mymodule'][‘cuddlySlider']
['foo'] = 'bar';
Drupal 8 - Inline JavaScript
• Inline JavaScript is discouraged.
• It's recommended to put the JS you want to use inline i...
Drupal 8 - Inline JavaScript
that generates markup
• Examples of this are ads, social media sharing buttons, social media
...
Drupal 8 - Inline JavaScript that
affects the entire page
• Example: Google Analytics. It should not be front end / stylin...
Drupal 8 - Inline JavaScript that
affects the entire page
<?php
function mymodule_page_attachments(array &$page) {
$page['...
Drupal 8
• Use “Strict Mode”
• "use strict";
• It catches some common coding bloopers, throwing exceptions.
• It prevents,...
Drupal 8 - Strict Mode
• Variables and Properties
• An attempt to assign foo = "bar"; where ‘foo’ hasn’t been defined
will...
Drupal 8 - Strict Mode
eval is evil
Drupal 8
More Libraries
Drupal 8
• jQuery 2
• underscore
• Backbone
• Modernizr
• CKEditor
Drupal 8
Thank you
• calin@dreamproduction.com
• d.o: mariancalinro
• @mariancalinro
• github.com/calin-marian
Upcoming SlideShare
Loading in …5
×

Drupal Javascript for developers

2,450 views

Published on

The presentation covers:
*Adding JS to the page, both at module and theme level
*Writing Drupal aware JS code
*Libraries management
*Ajax framework
*Drupal JS functions
*Drupal JS theme functions

Published in: Internet
  • ♣♣ 10 Easy Ways to Improve Your Performance in Bed... ★★★ https://tinyurl.com/rockhardxxx
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

Drupal Javascript for developers

  1. 1. Drupal Javascript for developers
  2. 2. Whoami? • C lin Mariană • Lead developer @ Dream Production • calin@dreamproduction.com • d.o: mariancalinro • @mariancalinro • github.com/calin-marian
  3. 3. What will we cover? • Adding JS to the page, both at module and theme level • Writing Drupal aware JS code • Libraries management • Ajax framework • Drupal JS functions • Drupal JS theme functions • If we have enough time … some Drupal 8 changes
  4. 4. Adding JS to page • declare it in the .info file of your module scripts[] = path/to/component.js • Using drupal_add_js() drupal_add_js(drupal_get_path(‘module’, ‘mymodule’) . ‘/path/to/component.js’); • attach it to a render array $build[‘myelement’] = array( ‘#theme’ => ‘my_theme’, ‘#myvar’ => $myvar, ‘#attached’ => array( ‘js’ => drupal_get_path(‘module’, ‘mymodule') . ‘/path/to/component.js’ ), );
  5. 5. Adding JS to page • declare it in the .info file of your module scripts[] = path/to/component.js • Using drupal_add_js() drupal_add_js(drupal_get_path(‘module’, ‘mymodule') . ‘/path/to/component.js’); • attach it to a render array $build[‘myelement’] = array( ‘#theme’ => ‘my_theme’, ‘#myvar’ => $myvar, ‘#attached’ => array( ‘js’ => drupal_get_path(‘module’, ‘mymodule') . ‘/path/to/component.js’ ), );
  6. 6. Adding JS to page • declare it in the .info file of your module scripts[] = path/to/component.js • Using drupal_add_js() drupal_add_js(drupal_get_path(‘module’, ‘mymodule') . ‘/path/to/component.js’); • attach it to a render array $build[‘myelement’] = array( ‘#theme’ => ‘my_theme’, ‘#myvar’ => $myvar, ‘#attached’ => array( ‘js’ => drupal_get_path(‘module’, ‘mymodule') . ‘/path/to/component.js’ ), );
  7. 7. Adding JS to page • declare it in the .info file of your module scripts[] = path/to/component.js • Using drupal_add_js() drupal_add_js(drupal_get_path(‘module’, ‘mymodule') . ‘/path/to/component.js’); • attach it to a render array $build[‘myelement’] = array( ‘#theme’ => ‘my_theme’, ‘#myvar’ => $myvar, ‘#attached’ => array( ‘js’ => drupal_get_path(‘module’, ‘mymodule') . ‘/path/to/component.js’ ), );
  8. 8. Adding JS to page • for a theme, there are 2 ways to add a JS file to the page: • declare it in the .info file of your theme, same as module scripts[] = path/to/component.js • Using drupal_add_js() from template.php, in the hook_preprocess_html() function
  9. 9. Adding JS to page • for a theme, there are 2 ways to add a JS file to the page: • declare it in the .info file of your theme, same as module scripts[] = path/to/component.js • Using drupal_add_js() from template.php, in the hook_preprocess_html() function
  10. 10. Adding JS to page • for a theme, there are 2 ways to add a JS file to the page: • declare it in the .info file of your theme, same as module scripts[] = path/to/component.js • Using drupal_add_js() from template.php, in the hook_preprocess_html() function
  11. 11. Closures (function ($) { // Code that uses jQuery's $ can follow here. $(‘a’).on(‘click’, function(event){ event.preventDefault(); alert(‘Links are disabled, you are trapped on this page. Hahahaha!!!’); }); var window = "Whoops, at least I only broke my code."; }(jQuery));
  12. 12. Closures (function ($) { // Code that uses jQuery's $ can follow here. $(‘a’).on(‘click’, function(event){ event.preventDefault(); alert(‘Links are disabled, you are trapped on this page. Hahahaha!!!’); }); var window = "Whoops, at least I only broke my code."; }(jQuery));
  13. 13. Closures (function ($) { // Code that uses jQuery's $ can follow here. $(‘a’).on(‘click’, function(event){ event.preventDefault(); alert(‘Links are disabled, you are trapped on this page. Hahahaha!!!’); }); var window = "Whoops, at least I only broke my code."; }(jQuery));
  14. 14. Settings <?php drupal_add_js(array( 'myModule' => array( 'key' => 'value' ) ), 'setting'); ================================== (function($){ console.log(Drupal.settings.myModule.key); // logs 'value' })(jQuery)
  15. 15. Settings <?php drupal_add_js(array( 'myModule' => array( 'key' => 'value' ) ), 'setting'); ================================== (function($){ console.log(Drupal.settings.myModule.key); // logs 'value' })(jQuery)
  16. 16. Settings <?php drupal_add_js(array( 'myModule' => array( 'key' => 'value' ) ), 'setting'); ================================== (function($){ console.log(Drupal.settings.myModule.key); // logs 'value' })(jQuery)
  17. 17. Behaviors • Drupal’s way of dealing with attaching and detaching functionalities to dynamic content. • Invoked by Drupal automatically when content is added or removed to the page by the Ajax framework • Objects in the namespace Drupal.behaviors that have the methods attach and detach - detach is optional if you do not need to run some code when content is removed from page.
  18. 18. Behaviors (function($){ Drupal.behaviors.myComponent = { attach: function(context, settings) { // Make your DOM manipulations and attach your // event handlers for your component. }, detach: function(context, settings) { // This is optional, use it if your component needs to destroy // variables to free memory, or do other tasks when the content // your component is attached to is removed from the DOM. } } })(jQuery)
  19. 19. Behaviors (function($){ Drupal.behaviors.myComponent = { attach: function(context, settings) { // Make your DOM manipulations and attach your // event handlers for your component. }, detach: function(context, settings) { // This is optional, use it if your component needs to destroy // variables to free memory, or do other tasks when the content // your component is attached to is removed from the DOM. } } })(jQuery)
  20. 20. Behaviors (function($){ Drupal.behaviors.myComponent = { attach: function(context, settings) { // Make your DOM manipulations and attach your // event handlers for your component. }, detach: function(context, settings) { // This is optional, use it if your component needs to destroy // variables to free memory, or do other tasks when the content // your component is attached to is removed from the DOM. } } })(jQuery)
  21. 21. Behaviors (function($){ Drupal.behaviors.myBxSlider = { attach: function(context, settings) { var options = settings.myBxSlider, Drupal.myBxSlider = $(options.sliderSelector, context) .bxSlider(options.sliderOptions); }, detach: function(context, settings) { delete Drupal.myBxSlider; } } })(jQuery)
  22. 22. Behaviors (function($){ Drupal.behaviors.myBxSlider = { attach: function(context, settings) { var options = settings.myBxSlider, Drupal.myBxSlider = $(options.sliderSelector, context) .bxSlider(options.sliderOptions); }, detach: function(context, settings) { delete Drupal.myBxSlider; } } })(jQuery)
  23. 23. Behaviors • When adding content to the page, call Drupal.attachBehaviors on the content. This allows other components to attach themselves to the content. The Ajax framework does this for you automatically. • Example: Drupal.attachBehaviors(insertedContent); • Bad example: Drupal.attachBehaviors(); • When run without context, the full page is the context. This means behaviors’ attach methods will run more than once, on the same content.
  24. 24. Behaviors • When adding content to the page, call Drupal.attachBehaviors on the content. This allows other components to attach themselves to the content. The Ajax framework does this for you automatically. • Example: Drupal.attachBehaviors(insertedContent); • Bad example: Drupal.attachBehaviors(); • When run without context, the full page is the context. This means behaviors’ attach methods will run more than once, on the same content.
  25. 25. Drupal once • To protect yourself against having your code run twice on the same content, Drupal implements a jQuery method, called once: $(selector).once(stringKey, handler) • The handler is only called once, no mater how many times the method is invoked on the same content. • It works by adding a class on the content, and checking for that class when it’s invoked. • Alternative usage: $(selector).once(‘myComponent’).wrap(‘<div class=“myWrapper”></div>’);
  26. 26. Drupal once (function($){ Drupal.behaviors.myExample = { attach: function(context, settings) { $(‘a’, context) .once(‘notification’) .click(function(event){ event.preventDefault(); alert(‘Links are disabled, you are trapped on this page. Hahahaha!!!’); }); } } })(jQuery);
  27. 27. Drupal once (function($){ Drupal.behaviors.myExample = { attach: function(context, settings) { $(‘a’, context) .once(‘notification’) .click(function(event){ event.preventDefault(); alert(‘Links are disabled, you are trapped on this page. Hahahaha!!!’); }); } } })(jQuery);
  28. 28. Drupal once (function($){ Drupal.behaviors.myExample = { attach: function(context, settings) { $(‘a’, context).once(‘notification’, function(){ $(this).click(function(event){ event.preventDefault(); alert(‘Links are disabled, you are trapped on this page. Hahahaha!!!’); }); }); } } })(jQuery);
  29. 29. Libraries • Allows you to add all the JavaScript and CSS of one component at once • Example: drupal_add_library('system', 'ui.accordion'); $build['#attached']['library'][] = array('system', ‘ui.accordion'); • hook_library - to define your library • hook_library_alter - to modify libraries provided by other modules
  30. 30. Libraries • Allows you to add all the JavaScript and CSS of one component at once • Example: drupal_add_library('system', 'ui.accordion'); $build['#attached']['library'][] = array('system', ‘ui.accordion'); • hook_library - to define your library • hook_library_alter - to modify libraries provided by other modules
  31. 31. Libraries • Allows you to add all the JavaScript and CSS of one component at once • Example: drupal_add_library('system', 'ui.accordion'); $build['#attached']['library'][] = array('system', ‘ui.accordion'); • hook_library - to define your library • hook_library_alter - to modify libraries provided by other modules
  32. 32. function system_library() { // ... $libraries['ui.accordion'] = array( 'title' => 'jQuery UI: Accordion', 'website' => 'http://jqueryui.com/demos/accordion/', 'version' => '1.7.2', 'js' => array( 'misc/ui/ui.accordion.js' => array(), ), 'css' => array( 'misc/ui/ui.accordion.css' => array(), ), 'dependencies' => array( array('system', 'ui'), ), ); return $libraries; }
  33. 33. function system_library() { // ... $libraries['ui.accordion'] = array( 'title' => 'jQuery UI: Accordion', 'website' => 'http://jqueryui.com/demos/accordion/', 'version' => '1.7.2', 'js' => array( 'misc/ui/ui.accordion.js' => array(), ), 'css' => array( 'misc/ui/ui.accordion.css' => array(), ), 'dependencies' => array( array('system', 'ui'), ), ); return $libraries; }
  34. 34. function system_library() { // ... $libraries['ui.accordion'] = array( 'title' => 'jQuery UI: Accordion', 'website' => 'http://jqueryui.com/demos/accordion/', 'version' => '1.7.2', 'js' => array( 'misc/ui/ui.accordion.js' => array(), ), 'css' => array( 'misc/ui/ui.accordion.css' => array(), ), 'dependencies' => array( array('system', 'ui'), ), ); return $libraries; }
  35. 35. function system_library() { // ... $libraries['ui.accordion'] = array( 'title' => 'jQuery UI: Accordion', 'website' => 'http://jqueryui.com/demos/accordion/', 'version' => '1.7.2', 'js' => array( 'misc/ui/ui.accordion.js' => array(), ), 'css' => array( 'misc/ui/ui.accordion.css' => array(), ), 'dependencies' => array( array('system', 'ui'), ), ); return $libraries; }
  36. 36. Ajax Framework • Ajax is a technique that updates content on the page from the server without page refresh. • Drupal’s Ajax framework helps you with this task. • It implements more than a few commands that you can trigger from the response of the Ajax call. • Does some boilerplate code.
  37. 37. Ajax Framework • ajax_command_insert() • ajax_command_before() • ajax_command_after() • ajax_command_replace() • ajax_command_invoke() • ajax_command_settings() • For the full list, google “Drupal Ajax framework commands”
  38. 38. Ajax Framework • A php array such as... array( 'command' => 'insert', 'method' => 'append', 'selector' => '#my-div', 'data' => '<div>Some new content</div>', ) • ... will turn into this object received on the js side: { command: insert, method: append, selector:#my- div, data: '<div>Some new content</div>' } • ... a clear instruction for ajax.js to follow
  39. 39. Ajax Framework • To implement new command in js: Drupal.ajax.prototype.commands.myCommand = function (ajax, response, status) { // in response you have an object with the properties // sent from php, such as myvar, selector, data. } • Then in php, you can return the following array from an Ajax call: array( 'command' => 'myCommand', 'myvar' => 'myvalue', 'selector' => '#my-div', 'data' => '<div>Some new content</div>', )
  40. 40. Ajax Framework Example
  41. 41. Ajax Framework • You print somewhere in the page this link: array( '#type' => 'link', '#title' => t('Ajax Link'), '#href' => 'my-ajax-test/nojs', '#suffix' => '<div id="ajax-display"></div>', '#ajax' => array( 'effect' => 'fade', ), );
  42. 42. Ajax Framework • You print somewhere in the page this link: array( '#type' => 'link', '#title' => t('Ajax Link'), '#href' => 'my-ajax-test/nojs', '#suffix' => '<div id="ajax-display"></div>', '#ajax' => array( 'effect' => 'fade', ), );
  43. 43. Ajax Framework • You print somewhere in the page this link: array( '#type' => 'link', '#title' => t('Ajax Link'), '#href' => 'my-ajax-test/nojs', '#suffix' => '<div id="ajax-display"></div>', '#ajax' => array( 'effect' => 'fade', ), );
  44. 44. Ajax Framework • Alternative way: array( '#type' => 'link', '#title' => t('Ajax Link'), '#href' => 'my-ajax-test/nojs', '#suffix' => '</div><div id="ajax- display"></div>', '#attributes' => array( 'class' => array(‘use-ajax’), ), );
  45. 45. Ajax Framework • You need to define a new menu item: $items['my-ajax-test/%'] = array( 'title' => 'Ajax test callback', 'type' => MENU_CALLBACK, 'page callback' => 'ajax_link_callback', 'page arguments' => array(1), 'access arguments' => array('access content'), );
  46. 46. Ajax Framework • You need to define a new menu item: $items['my-ajax-test/%'] = array( 'title' => 'Ajax test callback', 'type' => MENU_CALLBACK, 'page callback' => 'ajax_link_callback', 'page arguments' => array(1), 'access arguments' => array('access content'), );
  47. 47. Ajax Framework • Then, define the callback for that menu item: function ajax_link_callback($ajax) { $time = t('The current time is: !time', array('!time' => date('Y-m-d H:i:s'))); if ($ajax == 'ajax') { $commands = array(); $commands[] = ajax_command_replace( '#ajax-display', "<div id='ajax-display'>" . $time . "</div>"); ajax_deliver(array( '#type' => ‘ajax', '#commands' => $commands)); } else { return array('#markup' => $time); } }
  48. 48. Ajax Framework • Then, define the callback for that menu item: function ajax_link_callback($ajax) { $time = t('The current time is: !time', array('!time' => date('Y-m-d H:i:s'))); if ($ajax == 'ajax') { $commands = array(); $commands[] = ajax_command_replace( '#ajax-display', "<div id='ajax-display'>" . $time . "</div>"); ajax_deliver(array( '#type' => ‘ajax', '#commands' => $commands)); } else { return array('#markup' => $time); } }
  49. 49. Ajax Framework • Then, define the callback for that menu item: function ajax_link_callback($ajax) { $time = t('The current time is: !time', array('!time' => date('Y-m-d H:i:s'))); if ($ajax == 'ajax') { $commands = array(); $commands[] = ajax_command_replace( '#ajax-display', "<div id='ajax-display'>" . $time . "</div>"); ajax_deliver(array( '#type' => ‘ajax', '#commands' => $commands)); } else { return array('#markup' => $time); } }
  50. 50. Ajax Framework • Then, define the callback for that menu item: function ajax_link_callback($ajax) { $time = t('The current time is: !time', array('!time' => date('Y-m-d H:i:s'))); if ($ajax == 'ajax') { $commands = array(); $commands[] = ajax_command_replace( '#ajax-display', "<div id='ajax-display'>" . $time . "</div>"); ajax_deliver(array( '#type' => ‘ajax', '#commands' => $commands)); } else { return array('#markup' => $time); } }
  51. 51. Ajax Framework • Then, define the callback for that menu item: function ajax_link_callback($ajax) { $time = t('The current time is: !time', array('!time' => date('Y-m-d H:i:s'))); if ($ajax == 'ajax') { $commands = array(); $commands[] = ajax_command_replace( '#ajax-display', "<div id='ajax-display'>" . $time . "</div>"); ajax_deliver(array( '#type' => ‘ajax', '#commands' => $commands)); } else { return array('#markup' => $time); } }
  52. 52. Ajax Framework • Then, define the callback for that menu item: function ajax_link_callback($ajax) { $time = t('The current time is: !time', array('!time' => date('Y-m-d H:i:s'))); if ($ajax == 'ajax') { $commands = array(); $commands[] = ajax_command_replace( '#ajax-display', "<div id='ajax-display'>" . $time . "</div>"); ajax_deliver(array( '#type' => ‘ajax', '#commands' => $commands)); } else { return array('#markup' => $time); } }
  53. 53. Ajax Forms • Ajax forms in Drupal are provided by the Form API. • You write the form using the Drupal Form API. • You do not write or see any Javascript.
  54. 54. Ajax Forms • Specifiy what form element activates the Ajax behavior by adding #ajax to it. • Specify what part of the form’s HTML is to be replaced by the callback using the ‘wrapper’ attribute. • Provide a callback function that receives the whole rebuild form, and returns the piece of form that will replace the wrapper content. • Your form builder needs to take into account $form_state[‘values’] when building the form. • Find examples in the Drupal Examples for Developers(examples) module.
  55. 55. Ajax Forms • Example of FAPI Ajax: $form['dropdown_first'] = array( '#type' => 'select', '#title' => 'Instrument Type', '#options' => $options_first, '#default_value' => $form_state['values']['dropdown_first'], '#ajax' => array( 'callback' => 'dependent_dropdown_callback', 'wrapper' => 'dropdown-second-replace', ), );
  56. 56. Ajax Forms • Example of FAPI Ajax: $form['dropdown_first'] = array( '#type' => 'select', '#title' => 'Instrument Type', '#options' => $options_first, '#default_value' => $form_state['values']['dropdown_first'], '#ajax' => array( 'callback' => 'dependent_dropdown_callback', 'wrapper' => 'dropdown-second-replace', ), );
  57. 57. Ajax Forms • Example of FAPI Ajax: $form['dropdown_second'] = array( '#type' => 'select', '#title' => $options_first[$selected] . ' ' . t('Instruments'), '#prefix' => '<div id="dropdown-second-replace">', '#suffix' => '</div>', '#options' => _get_second_dropdown_options( $form_state['values']['dropdown_first']), '#default_value' => $form_state['values']['dropdown_second'], );
  58. 58. Ajax Forms • Example of FAPI Ajax: $form['dropdown_second'] = array( '#type' => 'select', '#title' => $options_first[$selected] . ' ' . t('Instruments'), '#prefix' => '<div id="dropdown-second-replace">', '#suffix' => '</div>', '#options' => _get_second_dropdown_options( $form_state['values']['dropdown_first']), '#default_value' => $form_state['values']['dropdown_second'], );
  59. 59. Ajax Forms • Example of FAPI Ajax: $form['dropdown_second'] = array( '#type' => 'select', '#title' => $options_first[$selected] . ' ' . t('Instruments'), '#prefix' => '<div id="dropdown-second-replace">', '#suffix' => '</div>', '#options' => _get_second_dropdown_options( $form_state['values']['dropdown_first']), '#default_value' => $form_state['values']['dropdown_second'], );
  60. 60. Ajax Forms function dependent_dropdown_callback($form, $form_state) { return $form['dropdown_second']; }
  61. 61. Ajax Forms function dependent_dropdown_callback($form, $form_state) { return $form['dropdown_second']; }
  62. 62. States • Provides interactive forms where the actual underlying form doesn't change, just the presentation to the user. • You mark a form element that is dependent on another element (opposite of #ajax) • You specify the condition and resultant action: 'checked' => array( ':input[name="more_info"]' => array('filled' => TRUE) ), • The Conditional fields (conditional_fields) module provides an UI for using this API on fields. • Find examples in the Drupal Examples for Developers(examples) module.
  63. 63. States $form['source'] = array( '#type' => 'checkboxes', '#options' => drupal_map_assoc(array( t(‘TV'), t(‘Newspaper’), t(‘Internet), t(‘Other…) )), '#title' => t(‘Where did you hear of us?'), );
  64. 64. States $form['source'] = array( '#type' => 'checkboxes', '#options' => drupal_map_assoc(array( t(‘TV'), t(‘Newspaper’), t(‘Internet), t(‘Other…) )), '#title' => t(‘Where did you hear of us?'), );
  65. 65. States $form[‘source_text’] = array( '#type' => 'textfield', '#title' => t(‘Write in a few words where you heard of us'), '#states' => array( 'visible' => array( ':input[name=source]' => array( 'value' => t(‘Other…’) ), ), ), );
  66. 66. States $form[‘source_text’] = array( '#type' => 'textfield', '#title' => t(‘Write in a few words where you heard of us'), '#states' => array( 'visible' => array( ':input[name=source]' => array( 'value' => t(‘Other…’) ), ), ), );
  67. 67. States $form[‘source_text’] = array( '#type' => 'textfield', '#title' => t(‘Write in a few words where you heard of us'), '#states' => array( 'visible' => array( ':input[name=source]' => array( 'value' => t(‘Other…’) ), ), ), );
  68. 68. Drupal.theme • Is the JavaScript counterpart to theme() • To define a theme function simply create a new public method for the Drupal.theme class: Dupal.theme.prototype.displayName = function(name, url) { return '<a href="' + url + '">' + name + '</a>'; } • Then invoke it through Drupal.theme when needed: var name = "John Doe"; var url = "http://example.com"; var display = Drupal.theme('displayName', name, url)
  69. 69. Drupal.theme • Is the JavaScript counterpart to theme() • To define a theme function simply create a new public method for the Drupal.theme class: Dupal.theme.prototype.displayName = function(name, url) { return '<a href="' + url + '">' + name + '</a>'; } • Then invoke it through Drupal.theme when needed: var name = "John Doe"; var url = "http://example.com"; var display = Drupal.theme('displayName', name, url)
  70. 70. Drupal.theme • Is the JavaScript counterpart to theme() • To define a theme function simply create a new public method for the Drupal.theme class: Dupal.theme.prototype.displayName = function(name, url) { return '<a href="' + url + '">' + name + '</a>'; } • Then invoke it through Drupal.theme when needed: var name = "John Doe"; var url = "http://example.com"; var display = Drupal.theme('displayName', name, url)
  71. 71. Drupal.theme • Another developer changes the implementation: Dupal.theme.prototype.displayName = function(name, url) { return ‘<div class=‘username-wrapper”><a href="' + url + '">' + name + ‘</a></div>'; } • All places where the theme function is used will now display the updated markup.
  72. 72. Drupal.theme • Allows you to alter the output of components defined by third parties. • Allows others to alter the output of your components. • In D7 there is only one theme implementation in core (placeholder).
  73. 73. Multilingual • Drupal has multilingual support in JS. • You can wrap your text in Drupal.t(), and it will be available for translation in the UI. If there is a translation for your text in the current language, it will be used. • It only works if the text is explicitly written inside the call to Drupal.t(), and not if it’s inside a variable. • Drupal.t(str, args, options) str - the string to be translated, has to be in English args - an object of replacement pairs to be made after translation options - options object, only ‘context’ key is used, defaults to empty string
  74. 74. Other API’s • autocomplete • FAPI property: '#autocomplete_path' => ‘some/path’, • the callback function for that path needs to return a JSON with matches in the format ‘value’ => ‘display_string’
  75. 75. Other API’s • autocomplete • FAPI property: '#autocomplete_path' => ‘some/path’, • the callback function for that path needs to return a JSON with matches in the format ‘value’ => ‘display_string’
  76. 76. Other API’s • autocomplete • FAPI property: '#autocomplete_path' => ‘some/path’, • the callback function for that path needs to return a JSON with matches in the format ‘value’ => ‘display_string’
  77. 77. Other API’s • tabledrag - drupal_add_tabledrag() • Assists in adding the tableDrag JavaScript behavior to a themed table • Draggable tables should be used wherever an outline or list of sortable items needs to be arranged by an end-user. Draggable tables are very flexible and can manipulate the value of form elements placed within individual columns. • not so simple to implement
  78. 78. Other API’s - tabledrag
  79. 79. Drupal 8 • Drupal.settings -> drupalSettings • Drupal.theme.prototype -> Drupal.theme • Drupal.ajax.prototype.commands -> Drupal.AjaxCommands.prototype
  80. 80. Drupal 8 • Only the JavaScript required on a particular page will be added to that page • jQuery is not automatically loaded on all pages anymore. • You have to declare a dependency for your code on jQuery to have jQuery loaded on the page
  81. 81. Drupal 8 - Defining a library *.libraries.yml in your module: cuddly-slider: version: 1.x css: theme: css/cuddly-slider.css: {} js: js/cuddly-slider.js: {} dependencies: - core/jquery
  82. 82. Drupal 8 - Attaching a library to existing content <?php function mymodule_element_info_alter(array &$types) { if (isset($types['table']) { $types['table']['#attached']['library'][] = 'mymodule/cuddly-slider'; } }
  83. 83. Drupal 8 - Attaching a library to new content <?php $build[‘your_element’]['#attached']['library'][] = ‘mymodule/cuddly-slider';
  84. 84. Drupal 8 - Attaching a library to pages hook_page_attachments(). Example from the Contextual links module <?php function contextual_page_attachments(array &$page) { if (!Drupal::currentUser() ->hasPermission('access contextual links')) { return; } $page['#attached']['library'][] = 'contextual/drupal.contextual-links'; }
  85. 85. Drupal 8 - Attaching settings $build[‘#attached']['drupalSettings']['mymodule'][‘cuddlySlider'] ['foo'] = 'bar';
  86. 86. Drupal 8 - Inline JavaScript • Inline JavaScript is discouraged. • It's recommended to put the JS you want to use inline in a file instead, because that allows that JavaScript to be cached on the client side. • It allows JavaScript code to be reviewed and linted
  87. 87. Drupal 8 - Inline JavaScript that generates markup • Examples of this are ads, social media sharing buttons, social media listing widgets. • Option 1: Put the script inside a custom block. • Option 2: Put the script inside a twig template.
  88. 88. Drupal 8 - Inline JavaScript that affects the entire page • Example: Google Analytics. It should not be front end / styling • hook_page_attachments() — define attached HTML <HEAD> data by using the 'html_head' key in the #attached property:
  89. 89. Drupal 8 - Inline JavaScript that affects the entire page <?php function mymodule_page_attachments(array &$page) { $page['#attached']['html_head'][] = [ // The data. [ '#tag' => 'script', '#value' => 'alert("Hello world!");', ], // A key, to make it possible to recognize this HTML <HEAD> element when altering. 'hello-world' ]; }
  90. 90. Drupal 8 • Use “Strict Mode” • "use strict"; • It catches some common coding bloopers, throwing exceptions. • It prevents, or throws errors, when relatively “unsafe” actions are taken (such as gaining access to the global object). • It disables features that are confusing or poorly thought out.
  91. 91. Drupal 8 - Strict Mode • Variables and Properties • An attempt to assign foo = "bar"; where ‘foo’ hasn’t been defined will fail. • Deleting a variable, a function, or an argument will result in an error. • Defining a property more than once in an object literal will cause an exception to be thrown
  92. 92. Drupal 8 - Strict Mode eval is evil
  93. 93. Drupal 8 More Libraries
  94. 94. Drupal 8 • jQuery 2 • underscore • Backbone • Modernizr • CKEditor
  95. 95. Drupal 8
  96. 96. Thank you • calin@dreamproduction.com • d.o: mariancalinro • @mariancalinro • github.com/calin-marian

×