Using Drupal 8 Modal API

Drupal 8 has come with many cool feature to trigger JavaScripts events from the Backend using classes like AjaxResponse and OpenDialogCommand. One of these cool features is the possibility to open modal windows to show content or forms in a modal window very very easily.

In this post I’ll show you how to use this API to put a simple HTML anchor to open and fill a modal window.

Preparing the Theme

In order to be able to use the modal API you need to include in your theme the jQuery UI scripts among other libraries required by Drupal. In your libraries.yml in your theme folder, be sure that under the dependencies branch you have these libraries to be included

dependencies:
  - core/jquery
  - core/jquery.ui
  - core/jquery.once
  - core/drupal.ajax
  - core/drupal.dialog
  - core/system
  - core/drupal
  - core/drupalSettings
  - core/drupal.dialog.ajax

If you have to do any change here be sure to rebuild the cache when the change is done.

The Frontend

This is the easiest part, you must include an anchor link with some attributes to indicate Drupal that you want to open a modal once is clicked. One of the attributes is the class with the value use-ajax, the second attribute is the data-accepts attribute that must have the value application/vnd.drupal-modal, last but not least, don’t forget to include the href attribute, without this attribute you will get a Js error and this API won’t work.

The result is something like this

<a class="use-ajax" data-accepts="application/vnd.drupal-modal" href="/your_controller/123">Directions &amp; Parking</a>

The backend

In the backend you need to implement a controller with a callback that handles the route used in the href and that provides an AjaxResponse with the command to open the modal.

Create a Route

In your module routing.yml add a route like this (replace the names for your needed code).

your_module.modal_route:
  path: /your_controller/{nid}
  defaults:
    _controller: '\Drupal\your_module\Controller\YourController::yourCallback'
  requirements:
    _format: 'html'
    _access: 'TRUE'

 

The Controller

Now, in your module folder, inside of src/Controller you need to create a class called YourController with a method called yourCallback to provide the response. Something like this.

<?php

namespace Drupal\your_module\Controller;

use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\OpenDialogCommand;
use Drupal\Core\Ajax\OpenModalDialogCommand;
use Drupal\Core\Controller\ControllerBase;
use Drupal\node\Entity\Node;

class YourController extends ControllerBase {
  
  /**
   * @return AjaxResponse
   */
  public function yourCallback($nid) {
    $node = Node::load($nid);
    $view = node_view($node, 'teaser');
    $html = render($view);
    
    $response = new AjaxResponse();
    $response->addCommand(new OpenModalDialogCommand(t('Modal Title'), $html));
    return $response;
  }
  
}

Once that is done, be sure that your module is enable, that your rebuilt the cache, that the route is correct, that you can get access etc.

If everything went ok, once you click the link you’ll see a nice modal being opened with the content of the response inside of it, here you have a sample.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.