drupal javascript for developers

96
Drupal Javascript for developers

Upload: dream-production

Post on 20-Aug-2015

1.183 views

Category:

Internet


4 download

TRANSCRIPT

Page 1: Drupal Javascript for developers

Drupal Javascript for developers

Page 2: Drupal Javascript for developers

Whoami?

• Călin Marian

• Lead developer @ Dream Production

[email protected]

• d.o: mariancalinro

• @mariancalinro

• github.com/calin-marian

Page 3: Drupal Javascript for developers

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

Page 4: Drupal Javascript for developers

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

Page 5: Drupal Javascript for developers

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

Page 6: Drupal Javascript for developers

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

Page 7: Drupal Javascript for developers

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

Page 8: Drupal Javascript for developers

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 modulescripts[] = path/to/component.js

• Using drupal_add_js() from template.php, in the hook_preprocess_html() function

Page 9: Drupal Javascript for developers

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 modulescripts[] = path/to/component.js

• Using drupal_add_js() from template.php, in the hook_preprocess_html() function

Page 10: Drupal Javascript for developers

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 modulescripts[] = path/to/component.js

• Using drupal_add_js() from template.php, in the hook_preprocess_html() function

Page 11: Drupal Javascript for developers

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

Page 12: Drupal Javascript for developers

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

Page 13: Drupal Javascript for developers

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

Page 14: Drupal Javascript for developers

Settings<?php

drupal_add_js(array(

'myModule' => array(

'key' => 'value'

)

), 'setting');

==================================

(function($){

console.log(Drupal.settings.myModule.key); // logs 'value'

})(jQuery)

Page 15: Drupal Javascript for developers

Settings<?php

drupal_add_js(array(

'myModule' => array(

'key' => 'value'

)

), 'setting');

==================================

(function($){

console.log(Drupal.settings.myModule.key); // logs 'value'

})(jQuery)

Page 16: Drupal Javascript for developers

Settings<?php

drupal_add_js(array(

'myModule' => array(

'key' => 'value'

)

), 'setting');

==================================

(function($){

console.log(Drupal.settings.myModule.key); // logs 'value'

})(jQuery)

Page 17: Drupal Javascript for developers

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.

Page 18: Drupal Javascript for developers

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)

Page 19: Drupal Javascript for developers

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)

Page 20: Drupal Javascript for developers

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)

Page 21: Drupal Javascript for developers

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)

Page 22: Drupal Javascript for developers

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)

Page 23: Drupal Javascript for developers

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.

Page 24: Drupal Javascript for developers

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.

Page 25: Drupal Javascript for developers

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

Page 26: Drupal Javascript for developers

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

Page 27: Drupal Javascript for developers

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

Page 28: Drupal Javascript for developers

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

Page 29: Drupal Javascript for developers

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

Page 30: Drupal Javascript for developers

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

Page 31: Drupal Javascript for developers

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

Page 32: Drupal Javascript for developers

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;

}

Page 33: Drupal Javascript for developers

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;

}

Page 34: Drupal Javascript for developers

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;

}

Page 35: Drupal Javascript for developers

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;

}

Page 36: Drupal Javascript for developers

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.

Page 37: Drupal Javascript for developers

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”

Page 38: Drupal Javascript for developers

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

Page 39: Drupal Javascript for developers

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

Page 40: Drupal Javascript for developers

Ajax FrameworkExample

Page 41: Drupal Javascript for developers

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

Page 42: Drupal Javascript for developers

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

Page 43: Drupal Javascript for developers

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

Page 44: Drupal Javascript for developers

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

Page 45: Drupal Javascript for developers

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

Page 46: Drupal Javascript for developers

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

Page 47: Drupal Javascript for developers

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

Page 48: Drupal Javascript for developers

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

Page 49: Drupal Javascript for developers

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

Page 50: Drupal Javascript for developers

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

Page 51: Drupal Javascript for developers

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

Page 52: Drupal Javascript for developers

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

Page 53: Drupal Javascript for developers

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.

Page 54: Drupal Javascript for developers

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.

Page 55: Drupal Javascript for developers

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

Page 56: Drupal Javascript for developers

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

Page 57: Drupal Javascript for developers

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

Page 58: Drupal Javascript for developers

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

Page 59: Drupal Javascript for developers

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

Page 60: Drupal Javascript for developers

Ajax Forms

function dependent_dropdown_callback($form, $form_state) {

return $form['dropdown_second'];

}

Page 61: Drupal Javascript for developers

Ajax Forms

function dependent_dropdown_callback($form, $form_state) {

return $form['dropdown_second'];

}

Page 62: Drupal Javascript for developers

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.

Page 63: Drupal Javascript for developers

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?'),

  );

Page 64: Drupal Javascript for developers

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?'),

  );

Page 65: Drupal Javascript for developers

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…’)

),

      ),

    ),

  );

Page 66: Drupal Javascript for developers

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…’)

),

      ),

    ),

  );

Page 67: Drupal Javascript for developers

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…’)

),

      ),

    ),

  );

Page 68: Drupal Javascript for developers

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)

Page 69: Drupal Javascript for developers

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)

Page 70: Drupal Javascript for developers

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)

Page 71: Drupal Javascript for developers

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.

Page 72: Drupal Javascript for developers

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

Page 73: Drupal Javascript for developers

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 Englishargs - an object of replacement pairs to be made after translationoptions - options object, only ‘context’ key is used, defaults to empty string

Page 74: Drupal Javascript for developers

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’

Page 75: Drupal Javascript for developers

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’

Page 76: Drupal Javascript for developers

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’

Page 77: Drupal Javascript for developers

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

Page 78: Drupal Javascript for developers

Other API’s - tabledrag

Page 79: Drupal Javascript for developers

Drupal 8

• Drupal.settings -> drupalSettings

• Drupal.theme.prototype -> Drupal.theme

• Drupal.ajax.prototype.commands -> Drupal.AjaxCommands.prototype

Page 80: Drupal Javascript for developers

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

Page 81: Drupal Javascript for developers

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

Page 82: Drupal Javascript for developers

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

  }

}

Page 83: Drupal Javascript for developers

Drupal 8 - Attaching a library to new content

<?php

$build[‘your_element’]['#attached']['library'][] =

‘mymodule/cuddly-slider';

Page 84: Drupal Javascript for developers

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

}

Page 85: Drupal Javascript for developers

Drupal 8 - Attaching settings

$build[‘#attached']['drupalSettings']['mymodule'][‘cuddlySlider']

['foo'] = 'bar';

Page 86: Drupal Javascript for developers

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

Page 87: Drupal Javascript for developers

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.

Page 88: Drupal Javascript for developers

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:

Page 89: Drupal Javascript for developers

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'

  ];

}

Page 90: Drupal Javascript for developers

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.

Page 91: Drupal Javascript for developers

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

Page 92: Drupal Javascript for developers

Drupal 8 - Strict Mode

eval is evil

Page 93: Drupal Javascript for developers

Drupal 8More Libraries

Page 94: Drupal Javascript for developers

Drupal 8

• jQuery 2

• underscore

• Backbone

• Modernizr

• CKEditor

Page 95: Drupal Javascript for developers

Drupal 8

Page 96: Drupal Javascript for developers

Thank you

[email protected]

• d.o: mariancalinro

• @mariancalinro

• github.com/calin-marian