Insertar un formulario en un modal emergente con CTools y Drupal 7

Este tutorial le muestra cómo insertar un formulario en un modal para que aparezca en su sitio después de que un usuario haga clic en un enlace. En este tutorial, crearemos una página que tiene un solo enlace. Cuando se hace click, un modal emergente mostrará un formulario con un cuadro de texto y un botón de envío. 

1. Crea un módulo personalizado


Para este tutorial crearemos un módulo personalizado para demostrar el código. Lo llamaremos mymodule y crearemos una carpeta para él en sites / all / modules. El primer archivo a crear es mymodule.info con el siguiente código:

Snippet
  name = My Module
  core = 7.x
  dependencies[]=ctools

2. Defina las rutas de enrutamiento en hook_menu

A continuación, cree también un archivo mymodule.module en la carpeta. Declararemos dos puntos finales a través del menú de enlace: - 1. "/ mymodule / page": una página a la que un usuario puede viajar y ver el enlace que, cuando se hace click, hará que aparezca un modal con el formulario en él. 2. "/ mymodule /% ctools_js": el segundo es una devolución de llamada que devuelve el HTML del formulario modal. El segundo argumento es una variable. Su valor será "nojs", si el navegador del usuario no maneja JavaScript, o "ajax" si lo hace.

Snippet
/**
 * Implements hook_menu().
 */
function mymodule_menu() {
  $items = array();
 
  $items['mymodule/page'] = array(
    'page callback' => 'mymodule_page',
    'access callback' => TRUE,
    'type' => MENU_CALLBACK,
  );
 
  $items['mymodule/%ctools_js'] = array(
    'page callback' => 'mymodule_callback',
    'page arguments' => array(1),
    'access callback' => TRUE,
    'type' => MENU_CALLBACK,
  );
 
  return $items;
}

3. Crea un generador de enlaces

Este pequeño fragmento de código es una función auxiliar para generar el enlace. Toma un argumento que es el texto del enlace y devuelve el HTML. Es importante para que ctools y el subsistema ajax en Drupal funcionen que la URL en el enlace ajax incluya un componente nojs y tenga una clase de ctools-use-modal

Snippet
  /**
 * Helper function to make a link.
 */
function _mymodule_make_link($link_text = '') {
  // Set a default value if no text in supplied.
  if (empty($link_text)) {
    $link_text = 'Magical Modal';
  }
 
  return '<div id="magical-modal-link">' . l($link_text, 'mymodule/nojs', array('attributes' => array('class' => 'ctools-use-modal'))) . '</div>';
}

4. Defina la devolución de llamada de la página

Esta es la página a la que el usuario irá y verá el enlace. Esta página debe incluir ctools modal JavaScript libraries.

Snippet
 /**
 * An example page.
 */
function mymodule_page() {
  // Load the modal library and add the modal javascript.
  ctools_include('modal');
  ctools_modal_add_js();
  return _mymodule_make_link('Magical modal');
}

5. Defina la devolución de llamada ajax

Esto es lo que se ejecuta cuando el navegador del usuario realiza una solicitud a "/ mymodule / nojs" o "/ mymodule / ajax". En el caso de nojs, el formulario completo debe devolverse normalmente. En el caso de "ajax", el sistema de entrega ajax devuelve la información sobre la creación de un modal.

Snippet
/**
 * Ajax menu callback.
 */
function mymodule_callback($ajax) {
  if ($ajax) {
    ctools_include('ajax');
    ctools_include('modal');
 
    $form_state = array(
      'ajax' => TRUE,
      'title' => t('MyModule Modal Form'),
    );
 
    // Use ctools to generate ajax instructions for the browser to create
    // a form in a modal popup.
    $output = ctools_modal_form_wrapper('mymodule_form', $form_state);
 
    // If the form has been submitted, there may be additional instructions
    // such as dismissing the modal popup.
    if (!empty($form_state['ajax_commands'])) {
      $output = $form_state['ajax_commands'];
    }
 
    // Return the ajax instructions to the browser via ajax_render().
    print ajax_render($output);
    drupal_exit();
  }
  else {
    return drupal_get_form('mymodule_form');
  }
}

6. Cree un formulario de ejemplo

Lo siguiente que debe hacer para este ejemplo es crear el formulario y su función de envío. En el punto 5, le dijimos a ctools que el nombre del formulario era "mymodule_form", así que creemos ese formulario ahora con un campo de texto y un botón de envío. Observará que el formulario en sí no tiene nada de especial y, por lo tanto, se podría utilizar cualquier formulario de Drupal.

Snippet
  /**
 * Drupal form to be put in a modal.
 */
function mymodule_form($form, $form_state) {
  $form = array();
 
  $form['new_link_text'] = array(
    '#type' => 'textfield',
    '#title' => t('Link text'),
  );
 
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Submit'),
  );
 
  return $form;
}

7. Cree la función de envío

Al enviar el formulario, queremos enviar los comandos ajax al navegador para descartar el modal y cambiar el texto en el enlace en el que hicimos click. Puede ver que la función ajax_command_replace está apuntando al div con el id establecido por nuestra función auxiliar en 3. En situaciones en las que no está usando su propio formulario sino algún otro en el sistema Drupal, es posible que deba agregar acciones ajax adicionales incluyendo su propias funciones de envío al formulario.

Snippet
/ **
 * Manejador de envío de formularios Drupal.
 * / 
function  mymodule_form_submit (& $ form, & $ form_state)  {
   // Genera el nuevo enlace usando el valor de texto enviado. 
  $ link = _mymodule_make_link ($ form_state [ 'valores' ] [ 'new_link_text' ]);
 
  // Dile al navegador que cierre el modal. 
  $ form_state [ 'ajax_commands' ] [] = ctools_modal_command_dismiss ();
 
  // Dile al navegador que reemplace el enlace antiguo por el nuevo. 
  $ form_state [ 'ajax_commands' ] [] = ajax_command_replace ( '# enlace-modal-mágico' , $ enlace);
}

8. Pruébelo


Ahora habilite el módulo mymodule y apunte su navegador a "/ mymodule / page". Debería ver un enlace con las palabras "Magical Modal". Hacer clic en el enlace debería abrir el formulario y enviar el formulario debería cambiar el texto del enlace.

Comments