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...

  • Let down by #phpstorm :-( no icon decorations on folders for version control status. Vote for it here: goo.gl/U6zRU 13 years 45 weeks ago
  • Having fun with #javascript, I mean #jquery, actually, I mean both :-p 13 years 46 weeks ago
  • Bitten by godaddy again, after a long time trying to make sense of my account I see I finally have nothing left on it. Bye bye! 13 years 46 weeks ago
  • ooh, jet profiler for mysql is pretty sweet 13 years 47 weeks ago
  • Here's some light friday afternoon reading, 26 Terabits per second: goo.gl/64ClB 13 years 47 weeks ago
  • A quick blog about setting up automated #Selenium testing with #Jenkins goo.gl/RQgaC 13 years 48 weeks ago
  • #ubuntu #gnome #canonical What features do you love that a KDE user should know about? Looking to add to my blog: goo.gl/Xmlk2 13 years 48 weeks ago
  • @philhawksworth I get the feeling you're going to start talking to yourself soon! 13 years 48 weeks ago
Oliver Polden