Theming
Topic

JavaScript in Drupal for Drupal 7, 8, 9, and 10

Whether you're trying to add your own JavaScript to a page, or make use of one of the many popular libraries provided by Drupal core, it's important to understand the asset library system when working with JavaScript in Drupal. By wrapping your JavaScript in an asset library it can be added to every page, selectively included when it's needed, or be easily modified by others.

In addition to the inclusion of third party libraries, Drupal core also contains numerous Drupal-specific JavaScript libraries that make it easier to do things like implement AJAX calls to a Drupal route, localize UI strings, and pass configuration stored in the database to the front-end. Drupal also contains several external projects in core like jQuery (but some components have been removed), Backbone, Underscore (removed in Drupal 10), and Modernizer (deprecated in Drupal 10; will be removed in Drupal 11).

Example tasks

  • Add custom JavaScript to a site
  • Utilize the JavaScript libraries that are included in Drupal core
  • Customize how JavaScript is loaded on a site to minimize the overall page size

Confidence

The asset library concept and associated methods are stable in Drupal. JavaScript library dependencies in Drupal core are the most likely to change or be removed (either partially or wholly). For example, here is a list of changes related to jquery in Drupal core. The Underscore.js library was removed in Drupal 10 and Modernizr has been deprecated in Drupal 10 and will be removed in Drupal 11.

Drupalize.Me resources

More information

JavaScript (JS) is an interpreted programming language that is widely used on the web to control web page behavior and interactivity.

Categories
Drupal 8, 9, and 10
More information

JavaScript is used and loaded in special ways within a Drupal site. JavaScript is loaded via asset libraries and Drupal core provides a bunch of different JavaScript libraries that you can load and use in your module or theme. This tutorial provides a brief orientation to some of the JavaScript included in core.

In this tutorial we'll:

  • Preview the JavaScript ecosystem in Drupal
  • Find pointers to tutorials where you can learn more about adding JavaScript to a theme or module
  • Learn about examples of JavaScript in Drupal core that are useful to review for learning purposes

By the end of this tutorial you should have a good overview of how JavaScript is used throughout Drupal core.

Categories
Drupal 8, 9, and 10
More information

An asset library is a bundle of CSS and/or JavaScript files that work together to provide a style and functionality for a specific component. They are frequently used to isolate the functionality and styling of a specific component, like the tabs displayed at the top of each node, into a reusable library. If you want to include CSS and/or JavaScript in your Drupal theme or module you'll need to declare an asset library that tells Drupal about the existence, and location, of those files. And then attach that library to a page, or specific element, so that it gets loaded when needed.

In this tutorial we’ll:

  • Define what an asset library is.
  • Explain why asset libraries are used to include JavaScript and CSS files.
  • Look at some example asset library definitions.

By the end of this tutorial you should be able to define what asset libraries are, and when you'll need to create one.

Categories
Drupal 8, 9, and 10
More information

New asset libraries can be defined by either modules or themes. In order to define a new asset library you need to create the requisite CSS and JavaScript files, and a new THEMENAME.libraries.yml, or MODULENAME.libraries.yml file that aggregates them together and provides metadata about the library itself and any dependencies.

In this tutorial we’ll:

  • Look at the structure of a *.libraries.yml file and demonstrate how to combine a couple of CSS and JS files together into an asset library that can be used in a theme or a module
  • Look at how one asset library can declare that it is dependent on another in order to ensure the assets from the dependency are loaded as well

By the end of this tutorial you should know how to define a new asset library in either a module or a theme.

Categories
Drupal 8, 9, and 10
More information

Once you've defined an asset library you'll need to tell Drupal when you want to add the CSS and JavaScript that it includes to the page. Ideally you'll do so in a way that allows Drupal to only add the corresponding assets on pages where they are needed.

You can attach a library to all pages, a subset of pages, or to elements in a render array. This allows you to have some assets that are global, and others that get loaded on an as-needed basis. To attach a library you'll need to know both its name and prefix, and then use one of the techniques outlined below to let Drupal know when to include it.

In this tutorial, we'll look at attaching asset libraries:

  • Globally, via your THEMENAME.info.yml file
  • Conditionally, via a preprocess function using the #attached render array property
  • Inside of a Twig template file

By the end of this tutorial you should be able to attach asset libraries in various different ways depending on your use case.

Integrating JavaScript with Drupal

More information

Anyone writing JavaScript for Drupal should use the Drupal.behaviors API when writing their custom JavaScript functionality. Doing so ensures that your JavaScript is executed at the appropriate times during the life cycle of a page, such as when the page loads, or after new DOM elements have been added via an AJAX request.

In this tutorial we'll look at:

  • The problem that Drupal.behaviors solves
  • How to use Drupal.behaviors when writing your JavaScript code

By the end of this tutorial you should be able to explain what the Drupal.behaviors API is, and be able to use it in your own JavaScript.

More information

It's often useful to pass dynamically calculated values from the server to the client in order to make them available to your front-end JavaScript. Your JavaScript might need to know something particular about the user currently visiting the site or the value of a particular configuration variable. In this tutorial, we'll look at how Drupal can pass these values from the PHP code that executes during a page load to the front-end JavaScript in your theme.

In order to do this, we'll need to:

  • Explain how drupalSettings bridges the gap between PHP and JavaScript
  • Generate values for settings in PHP and make them available to JavaScript
  • Make use of PHP generated settings within your JavaScript code
Categories
Drupal 8, 9, and 10
More information

You may know that Drupal provides utility PHP functions for manipulating and sanitizing strings. Drupal also provides JavaScript functions for the same purpose. The two most useful are Drupal.checkPlain and Drupal.formatPlural. Drupal.checkPlain lets you ensure a string is safe for output into the DOM; it is useful when working with user-provided input. Drupal.formatPlural ensures that a string containing a count of items is pluralized correctly. This tutorial will show you where you can find documentation for and example use-cases of both.

More information

Sometimes your JavaScript needs to insert new strings into the user interface. In order to ensure that those user-facing strings can be translated into other languages, just like the rest of Drupal's user interface, you should make sure and use the Drupal.t function anytime you output a string of text.

More information

In Drupal, whenever we output markup it's best practice to use a Twig template or a theme function. But whenever you need to output DOM elements within JavaScript the best practice is to use the Drupal.theme function. This function ensures that the output can be overridden just like the HTML output by Twig. This tutorial covers how to use the Drupal.theme function in your JavaScript when inserting DOM elements, as well as how to replace the markup output by other JavaScript code that is using the Drupal.theme function.

Categories
Drupal 8, 9, and 10
More information

Maybe you've heard of anonymous closures but you're not quite sure how they apply in Drupal, or why using them is considered a best-practice. Anonymous closures allow you to avoid accidentally clashing with anything in the global scope, as well as to alias the jQuery object to the more commonly used $. This is necessary because Drupal runs jQuery in no-conflict mode. This tutorial will look at the syntax used for placing your custom JavaScript code inside an anonymous closure, and why it's a good idea to do so.

In this tutorial we'll:

  • Explain what a closure is (briefly), and what immediately invoked function expressions are
  • Show how typically Drupal JavaScript gets wrapped in a closure
  • Provide a copy/paste example you can use in your own code

By the end of this tutorial you should be able to explain what an anonymous closure is, and how to use one in your custom JavaScript for Drupal.

Categories
Drupal 8, 9, and 10
More information

ESLint is the linting tool of choice for JavaScript in Drupal. In this tutorial we’ll show how to install the ESLint application and then use it to verify that your JavaScript files are meeting the Drupal coding standards.

Drupal (as of version 8.4) has adopted the Airbnb JavaScript coding standards. In this tutorial, we'll walk through how to install the necessary package dependencies to run eslint on JavaScript files within your Drupal site.

Using Ajax in Forms

Categories
Drupal 8, 9, and 10
More information

Asynchronous JavaScript And XML (Ajax) is a programming practice for building more complex, dynamic webpages using a technology known as XMLHttpRequest. It allows you to asynchronously perform server-side operations without requiring a refresh, thus allowing for more complex user interaction and, in some cases, improved user experience.

In this tutorial we'll:

  • Define what Ajax is
  • Look at how Ajax is implemented in the Drupal Form API
  • Provide links to additional resources to learn more about implementing Ajax in your own forms

By the end of this tutorial you should be able to explain what Ajax is, when you might want to use it, and how to get started doing so with Drupal's Form API.

More information

A common use of Ajax is to alter a form by adding, removing, or updating parts of the form in response to actions taken by the user. The resulting altered form is still eventually submitted with a traditional HTTP POST request. For example, one might update the options available in a city dropdown field after someone has chosen a value in the country dropdown, or add an additional textfield for collecting a person's name when the user clicks an "Add another person" button.

In this tutorial we'll:

  • Understand why certain types of modifications to a form require the use of Ajax
  • Use #ajax in conjunction with a <select> field to demonstrate how to update a form with Ajax
  • Learn about responding to user interaction with #ajax

By the end of this tutorial you should be able to use the #ajax attribute on any form element to respond to user actions and update the form displayed to the user with new content and options.

Categories
Drupal 8, 9, and 10
More information

Using Ajax allows you to create forms that are submitted to the server, and processed, without requiring a page reload.

In this tutorial we'll:

  • Use #ajax with a '#type' => 'submit' button in order to submit a form via Ajax
  • Look at how form build, validation, and processing are used when submitting a form via Ajax
  • Use the form's internal storage to track data across multiple requests
  • Discuss some best practices to keep in mind when using Ajax for form submissions

By the end of this tutorial you should know how to update an existing form so that it is submitted via Ajax and no longer requires a page refresh to work.

JavaScript libraries in core

Categories
Drupal 8, 9, and 10
More information

It's probably not too surprising that a library called Backbone aims to provide structure to your front-end JavaScript code and applications. In this tutorial we'll take a look at how Backbone.js goes about achieving that goal, and how you can make use of it on your Drupal site. We'll first take a high-level look at the main components that make up the Backbone.js library. With that basic understanding in place we'll look at an example of how you might integrate Backbone.js into a Drupal site.

More information

Underscore.js is a very small library which provides several utility functions and helpers to make working with JavaScript a little bit easier. In this tutorial we'll take a look at a part of the library, learn where the full library is documented, and see how we can make use of Underscore.js in a custom block on our Drupal site.

Categories
Drupal 8, 9, and 10
More information

In developing the theme for your website it's important to take accessibility into account. Making your site available and functional for as many users as possible is always a good idea. Progressive enhancement and graceful degradation are key, but how do you go about accounting for the minute differences between browser capabilities? This is where the Modernizr.js library can help you out.

Modernizr is a collection of browser detection tests which allow you, in either CSS or JavaScript, to determine if a particular browser supports a large list of features. From there it can automatically add classes to your page depending on the results of a particular feature test. It can also be used to create additional custom tests. In this tutorial we'll take a look at a few of the feature detection tests that Modernizr natively supports as well as how a custom test can be added to a Drupal theme.

Guides

Not sure where to start? Our guides provide useful learning tracks for all skill levels.

Navigate guides

External resources

Changes

  • [9.5.0/10.0.0] Added a new 'add_js' Ajax command (Drupal.org)
    • Ajax commands can now return a promise to ensure that the command is complete before executing the next Ajax command in the queue.
    • The Drupal.Ajax.prototype.success method now returns a promise, if your code overrides this method, make sure to return a promise.