Ventanas modales en Drupal 8

Últimamente estoy utilizando mucho CTools (Chaos Tools Suite). Es un módulo que suele pasar desapercibido, pero tiene muchas opciones interesantes a la hora de desarrollar portales, entre ellas:

  • Ventanas modales
  • Plugins extensibles
  • Formularios multipaso

El uso de ventanas modales con CTools es muy sencillo, y a la vez permite gestionar fácilmente las peticiones con navegadores que no tienen Javascript activado, permitiendo así proporcionar una alternativa amigable.

Con la llegada de Drupal 8, al fin tenemos Views en el core. El módulo Views es el contrib más instalado, creado por merlinofchaos, y en su versión 3.x, dependía de CTools para el uso de ventanas modales en su administración. ¿Qué pasará ahora que Views está en el core? ¿CTools también estará en el core? La respuesta es NO...

En lugar de eso, el equipo de la iniciativa de Views en el core ha decidido utilizar jQuery UI Dialog. Si ya está en el core desde Drupal 7, ¿por qué no utilizarlo? Además, es una solución más general y con más opciones que el desarrollo a medida de CTools.

Hay varios ejemplos sobre cómo se crean las ventanas modales de CTools en Drupal 7, además de algún ejemplo acerca de cómo crear ventanas modales de CTools varios estilos personalizados.

Entonces, ¿cómo se crean en Drupal 8? A continuación muestro un ejemplo simple acerca de cómo hacerlo teniendo en cuenta si el usuario utiliza o no Javascript:

./modaltest.info.yml

name: 'Modaltest'
type: module
description: 'Modal test'
core: 8.x

./modaltest.module

<?php
  // A .module file is required.

./modaltest.routing.yml

modaltest.page:
  path: '/modaltest'
  defaults:
    _title: 'Modal Test'
    _content: '\Drupal\modaltest\Controller\ModaltestController::page'
  requirements:
    _permission: 'access content'
modaltest.modal:
  path: '/modaltest/modal/{js}'
  defaults:
    _title: Modal
    _content: '\Drupal\modaltest\Controller\ModaltestController::modal'
  requirements:
    _permission: 'access content'
    js: 'nojs|ajax'

./lib/Drupal/modaltest/Controller/ModaltestController.php

<?php

namespace Drupal\modaltest\Controller;

use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\OpenModalDialogCommand;
use Drupal\Core\Controller\ControllerBase;

class ModaltestController extends ControllerBase {

  public function page() {
    return array(
      '#type' => 'markup',
      '#markup' => l(
        t('Link'),
        'modaltest/modal/nojs',
        array(
          'attributes' => array(
            'class' => 'use-ajax',
          ),
        )
      ),
      '#attached' => array(
        'library' => array(
          array('system', 'drupal.ajax'),
        ),
      ),
    );
  }

  public function modal($js = 'nojs') {
    if ($js == 'ajax') {
      $options = array(
        'width' => '80%',
      );
      $response = new AjaxResponse();
      $response->addCommand(
        new OpenModalDialogCommand(t('Modal'), t('This is the modal with Javascript.'), $options)
      );
      return $response;
    }
    else {
      return t('This is the page without Javascript.');      
    }
  }

}

En el caso de que estemos utilizando HTML5, podemos utilizar los atributos data-options para configurar las opciones del diálogo modal, y utilizar el atributo data-accepts si existe la posibilidad de devolver la misma respuesta con o sin Javascript, tal y como se explica en este artículo.

A continuación muestro cómo quedarían los archivos modaltest.routing.yml y ModaltestController.php en este caso:

./modaltest.routing.yml

modaltest.page:
  path: '/modaltest'
  defaults:
    _title: 'Modal Test'
    _content: '\Drupal\modaltest\Controller\ModaltestController::page'
  requirements:
    _permission: 'access content'
modaltest.modal:
  path: '/modaltest/modal'
  defaults:
    _title: Modal
    _content: '\Drupal\modaltest\Controller\ModaltestController::modal'
  requirements:
    _permission: 'access content'

./lib/Drupal/modaltest/Controller/ModaltestController.php

<?php

namespace Drupal\modaltest\Controller;

use Drupal\Core\Controller\ControllerBase;

class ModaltestController extends ControllerBase {

  public function page() {
    return array(
      '#type' => 'markup',
      '#markup' => l(
        t('Link'),
        'modaltest/modal',
        array(
          'attributes' => array(
            'class' => 'use-ajax',
            'data-accepts' => 'application/vnd.drupal-modal',
            'data-dialog-options' => '{"width": "80%"}',
          ),
        )
      ),
      '#attached' => array(
        'library' => array(
          array('system', 'drupal.ajax'),
        ),
      ),
    );
  }

  public function modal() {
    return t('This is the page without Javascript and the modal with Javascript.');      
  }

}

1 Comment

Añadir nuevo comentario

Plain text

  • No se permiten etiquetas HTML.
  • Las direcciones de las páginas web y las de correo se convierten en enlaces automáticamente.
  • Saltos automáticos de líneas y de párrafos.
By submitting this form, you accept the Mollom privacy policy.