Drupal popup forms

I've been trying to find a standardised way of creating popup forms that appear in a lightbox. Everything just seemed too inelegant. Then it hit me... Why not use the Drupal menu system itself to form the basis of this functionality?

First of all, this is for Drupal 6 but the technique is probably almost identical for Drupal 7.

How it's done.

Whenever I build something, I always build an HTML fallback. I usually find it makes you think in the right way and greatly simplifies coding. So first of all you build a normal menu item where the page callback is 'drupal_get_form'.

<?php
  $items
['path-to-my-form'] = array(
   
'title' => t('The form I want as a popup.'),
   
'page callback' => 'drupal_get_form',
   
'page arguments' => array('my_popup_form'),
   
'access callback' => TRUE, // Set up your own access checking
   
'type' => MENU_CALLBACK,
  );
?>

Next create your form:

<?php
 
function my_popup_form() {
   
$form['mytextfield'] = array(
     
'#type' => 'textfield',
     
'#title' => t('My textfield'),
    );
    return
$form;
  }
?>

You should now have a normal form that just shows a text field. Now for the actual guts of the system (by the way, some of you may have realised that you don't actually have to do the stuff above because this works for any Drupal form).

We will create another menu item:

<?php
  $items
['popup'] = array(
   
'page callback' => 'my_popup_popup',
   
'access arguments' => array('access content'),
   
'type' => MENU_CALLBACK,
  );
?>

This means we can create a path such as 'popup/admin/content/node'.

And define the callback:

<?php
 
function my_popup_popup() {
   
$args = func_get_args();
   
$menu_item = menu_get_item(implode('/', $args));
    if (
call_user_func_array($menu_item['access_callback'], unserialize($menu_item['access_arguments']))) {
      if (
$menu_item['page_callback'] == 'drupal_get_form') {
       
$output = drupal_get_form($menu_item['page_arguments']);
      }
      else {
       
$output = t('This is not a drupal_get_form callback.');
      }
    }
    else {
     
drupal_access_denied();
    }
    return
$output;
  }
?>

So when we visit any path beginning with 'popup', we can append the usual Drupal path and if the page callback is drupal_get_form, then we return the rendered form.

So now go and visit 'popup/admin/content/node'... Looks pretty much the same right? Good! You're nearly there.

Now in your active theme add a page-popup.tpl.php and add the following:

  <div class="popup">
    <?php
     
print $content;
   
?>

  </div>

Flush your theme registry and now you should only get the form itself.

Now all you need to do is write some JavaScript to take a link with perhaps a class of 'popup', and when you click it, to prepend popup to the beginning of the path to get the contents of the popup.

Actually, now that I've finished writing this, I realise that you could actually use this for any type of callback! Just call the callback in the menu item and pass the arguments in the same way I did the access check! You also need to make sure any files are included:

<?php
function dh_seo_popup_drupal() {
 
$args = func_get_args();
 
$menu_item = menu_get_item(implode('/', $args));
  include_once(
$menu_item['file']);
  if (
call_user_func_array($menu_item['access_callback'], unserialize($menu_item['access_arguments']))) {
   
$output = call_user_func_array($menu_item['page_callback'], $menu_item['page_arguments']);
  }
  else {
   
drupal_access_denied();
  }
  return
$output;
}
?>

In Drupal 7 you can use

In Drupal 7 you can use https://drupal.org/project/popup_forms

Yes, that's great. Drupal 7

Yes, that's great. Drupal 7 has some major improvements over Drupal 6.

Thank you,
Oliver

Post new comment

By submitting this form, you accept the Mollom privacy policy.

User login

Author of...

  • Ever wanted to create a CSS class or id from any old string in #Drupal? ctools_cleanstring() in the ctools module is your friend. 13 years 23 weeks ago
  • How to inspect the :active and :hover pseudo CSS style: http://t.co/zVANhKLp 13 years 24 weeks ago
  • @iainfarrell Good luck up north! 13 years 24 weeks ago
  • My most intriguing #Drupal utility modules out of 1030 for erm... Drupal 6, http://t.co/kmXV4qLp 13 years 24 weeks ago
  • #Chrome please can you check my hosts file before doing a search on an internet. Also, if I edit a url, yes that's still my local machine. 13 years 24 weeks ago
  • Seeing (not provided) in your Google Analytics?.. http://t.co/rSlpwm7U 13 years 25 weeks ago
  • Why SEO isn't evil http://t.co/MHh7ZHkK 13 years 25 weeks ago
  • @philhawksworth But that's unpossible! 13 years 26 weeks ago
Oliver Polden