Add a Time Form Element to Your Next Module Or Mini Module

Last modified: September 5, 2009 - 00:14

Drupal already has a date form type by default, but have you ever needed a time form element? This is a short snippet of code designed to allow you to insert a time element into your forms.

Drupal 5

<?php

function <your_modules_name>_elements() {
 
$type['pc_call_logs_time'] = array(
   
"#input" => true,
   
"#process" => array("pc_call_logs_expand_time" => array()),
  );

  return
$type;
}

function <
your_modules_name>_expand_time($element) {
 
// Default to current time, check default_value but set value so that if
  // default value is present it will override value
 
if (empty($element['#default_value'])) {
      
$element['#value'] = array(
     
'hour' => intval(format_date(time(), 'custom', 'h')),
     
'minute' => intval(format_date(time(), 'custom', 'i')),
     
'meridiem' => format_date(time(), 'custom', 'a'),
    );
  }
 
 
$element['#tree'] = TRUE;

  foreach (
$element['#value'] as $type => $value) {
    switch (
$type) {
      case
'hour':
       
$options = drupal_map_assoc(range(1, 12));
        break;
      case
'minute':
       
$options = range(0, 59);
        break;
      case
'meridiem':
       
$options = drupal_map_assoc(array('am', 'pm'));
        break;
    }
   
    if (
$type != 'meridiem') {
      foreach (
$options as $option) {
       
strlen($option) <= 1 ? $options[$option] = 0 . $option : '';
      }
    }

   
$element[$type] = array(
     
'#type' => 'select',
     
'#default_value' => $element['#value'][$type],
     
'#options' => $options,
    );
  }

  return
$element;
}

function
t<your_modules_name>_time($element) {
 
$output = '<div class="container-inline">'. $element['#children'] .'</div>';
  return
theme('form_element', $element, $output);
}

?>

To use the code, where you would normally define one of the fapi types you will now call <your_modules_name>_time. Here's an example...

<?php

  $form
['time'] = array(
   
'#type' => '<your_modules_name>_time',
   
'#title' => t('time'),
   
'#default_value' => array('hour' => '', 'minute' => '', 'meridiem' => ''),
  );

?>

The nice thing about this code is that it defaults to the current time, and it uses drupal date/time functions so it should take into account several time factors.

Drupal 6

Where the module says pc_call_logs it needs to actually be <your_modules_name>. Also, the => array() will cause this to fail so it needs to be taken out...

function games_elements() {
  $type['<custom_type>'] = array(
    "#input" => true,
    "#process" => array('<module_name>_expand_time'),
  );

  return $type;
}

A hook_theme() implementation needs to be added:

/**
* Implementation of hook_theme().
*/
function <module_name>_theme($existing, $type, $theme, $path) {
  return array(
    'games_time' => array(
      'arguments' => array('element' => NULL),
    ),
  );
}

And the element needs to have a theme processing function formatted like this:

function theme_<custom_type>($element) {
  $output = '<div class="container-inline">'. $element['#children'] .'</div>';
  return theme('form_element', $element, $output);
}

 
 

Drupal is a registered trademark of Dries Buytaert.