23

I have a form and I am using Drupal 7. I need to show this form in a popup when a user clicks a link. The user should then be able to complete the form whilst in the pop up window. I can use anything like Colorbox or modals or anything. I just wanted to know which is the better option and what options do I have for Drupal.

closed as primarily opinion-based by kiamlaluno Oct 27 '17 at 8:23

Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise. If this question can be reworded to fit the rules in the help center, please edit the question.

11

There's 2 good options I know of currently: iframe (in colorbox for example) and CTools. Which option to use depends of the circumstances. I guess this information I found in the CTools modal.html file brings out the main difference:

CTools provides a simple modal that can be used as a popup to place forms. It differs from the normal modal frameworks in that it does not do its work via an iframe. This is both an advantage and a disadvantage. The iframe simply renders normal pages in a sub-browser and they can do their thing. That makes it much easier to put arbitrary pages and forms in a modal. However, the iframe is not very good at actually communicating changes to the main page, so you cannot open the modal, have it do some work, and then modify the page.

I have no personal experienced with CTools on this subject so I can't add anything else to that, but I've implemented the iframe method in a couple of projects. In the most recent one I used the Colorbox plugin to show a few forms created with the Webform module in a popup. I'll add some example code here in case there's some interest.

Link to the form:

<a class="colorbox_form" href="'.url('node/5').'">'.t('Send message').'</a>

Javascript code to open the linked address in a popup:

if ($('a.colorbox_form').length > 0) {
  var link = $("a.colorbox_form").attr('href');
  link = link.concat('?colorbox=true');
  // colorbox=true is attached for later use (read below).
  $("a.colorbox_form").attr('href', link);
  $("a.colorbox_form").colorbox({iframe:true, width:500, height:450});
}

In the theme template file:

function mytheme_preprocess_page(&$variables) {
  // Different template and additional stylsheet for colorbox content.
  if (isset($_GET['colorbox']) && $_GET['colorbox'] == TRUE) {
    $variables['theme_hook_suggestions'] = array('page__iframe'); // page--iframe.tpl.php
    drupal_add_css(path_to_theme() .'/iframe.css');
    $variables['styles'] = drupal_get_css();
  }
}

I attached 'colorbox=true' to the links using javascript so that users with javascript turned off would see the form with the normal template. The iframe template only has messages, title and content printed.

This already works, but I ran into a issue with Webforms: 'colorbox=true' wasn't preserved when the form got submitted. My attempt to fix it:

function mymodule_form_alter(&$form, &$form_state, $form_id) {
  if (isset($_GET['colorbox']) && $_GET['colorbox'] == TRUE) {
    // The id-s of the forms that are possibly shown within a popup.
    $form_ids = array('webform_client_form_2', 'webform_client_form_4');
    if (in_array($form_id, $form_ids)) {
      $form['#submit'][] = 'mymodule_webform_submit';
    }
  }
}

function mymodule_webform_submit(&$form, &$form_state) {
  //drupal_set_message('<pre>'.var_export($form_state['redirect'], TRUE).'</pre>');
  if (!isset($form_state['redirect'])) {
    $form_state['redirect'] = array($_GET['q'], array('query' => array('colorbox' => 'true')));
  }
  else {
    $form_state['redirect'][1]['query'] = array('colorbox' => 'true');
  }
}
8

Use CTools which can insert a form into a modal when a user clicks a link.

Please check the following tutorial: Insert a form into a pop-up modal with CTools and Drupal 7 which simplifies this process in few steps.

Basically you need to define your hook_menu() callback for your modal form:

$items['mymodule/%ctools_js'] = array(
  'page callback' => 'mymodule_callback',
  'page arguments' => array(1),
  'access callback' => TRUE,
  'type' => MENU_CALLBACK,
);

then create a link generator which returns the HTML code:

/**
 * 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>';
}

so it can be used in your page callback, e.g.:

/**
 * 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');
}

When user clicks on the link, it makes request either to /mymodule/ajax or /mymodule/nojs (in case of nojs), so the following callback handles creating a modal:

/**
 * 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');
  }
} 

Now you just need to create a form and its submit handler as below:

/**
 * 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;
}

/**
 * Drupal form submit handler.
 */
function mymodule_form_submit(&$form, &$form_state) {
  // Generate the new link using the submitted text value.
  $link = _mymodule_make_link($form_state['values']['new_link_text']);

  // Tell the browser to close the modal.
  $form_state['ajax_commands'][] = ctools_modal_command_dismiss();

  // Tell the browser to replace the old link with the new one.
  $form_state['ajax_commands'][] = ajax_command_replace('#magical-modal-link', $link);
}

To test that, go to: /mymodule/page where you should see 'Magical Modal' link which should show you the modal form once clicked.

6

I would start looking at Modal form, instead of Colorbox. It specifically exists because using Colorbox with forms works really bad.

In modal form, Ctools does all the work in background, which has proper support for form handling that just doesn't belong in Colorbox. That also means that if you need to "modal" an unsupported form then you always know that thanks to Ctools there's a solid API behind it that you can switch to instead.

Bonus points for filing a patch with new form support if you write it. ;)

  • I disagree with the Modal Form recommendation, or at least add a qualifier - it only works with Log In, Request Password, Create New Account and Contact forms by default, and these are hardcoded. You cannot currently use it with arbitrary forms. Your best bet, at this point, may be to implement modal forms via a custom module using the ctools modal window API, using modal_forms as a model. – BrianV Jan 4 '12 at 19:07
  • I have updated my answer to weigh more heavily towards the Ctools part, though if Modal Form in itself solves the problem, even better. – Letharion Jan 4 '12 at 20:00
  • Seconded. The Colorbox module page now recommends not using Colorbox for this as well; support for this feature was removed from the 2.x series of Colorbox. – Patrick Kenny Mar 28 '13 at 14:29
2

I find that Simple Dialog is a great way to provide forms in Modals. It has the advantage of using jQuery UI which is in core.

All you need to do is provide a link to the form with some additional information. It provides a simple method based on classes and rel tags, or a theme method for more fine-tuned control. I've done this in two ways:

  1. The Menu Attributes module to provide the required rel and class tags.
  2. theme_menu_link to override menu link render functions.
  • Hello. Could you expand your answer a bit? What are required rel and class tags? Where can they be set up, if applicable? – Mołot Aug 20 '13 at 10:19
  • @Queenvictoria, could you please provide an example for how to open a form in popup window using Simple Dialog module? – ARUN Apr 30 '14 at 19:48
2

The module you need is https://drupal.org/project/popup_forms, but you need to do some programming in order to apply it (i.e. it can't be just configured via admin interface).

  • But the module doesn't have a stable release. – Mathankumar Oct 7 '13 at 10:01
  • The dev release works just fine. – Felix Eve Dec 5 '13 at 10:04

Not the answer you're looking for? Browse other questions tagged or ask your own question.