[development] custom form elements

Jakob Petsovits jpetso at gmx.at
Tue Nov 6 12:47:38 UTC 2007


On Tuesday, 6. November 2007, domas wrote:
> Hi,
> I need to let users submit locations in a form (using googlemaps) and I
> was thinking if it is possible to define custom form fields for formapi?
> Like $map = array('#type' => 'map', '#default_value' => 'xxx yyy',
> '#title' => 'your location') and have this show up as a map in the form.
>
> Is it possible to do this? How should this be done?

Have a look at hook_elements(). Using that, you can have custom form elements 
with an arbitrary set of properties. The only thing that's fixed is 
the '#process' handler, everything else depends on which properties you want 
to provide.

Here's an example from my Temporary Invitation module. Probably not the best 
one, but short and the one that I've got at hand right now:

/**
 * Implementation of hook_elements():
 * Register the duration widget with the Forms API and set default values.
 */
function temporary_invitation_elements() {
  $type['duration'] = array(
    // the $form_values elements will be named '#name'_metric
    // and '#name'_value
    '#name' => 'duration',
    '#default_metric' => 'mon',
    '#default_value' => 1,
    '#process' => array('_temporary_invitation_duration_process' => array()),
  );
  return $type;
}

/**
 * The process hook for 'duration' type widgets.
 * Called after defining the form and while building it.
 */
function _temporary_invitation_duration_process($element) {
  $name = $element['#name'];
  $element[$name .'_value'] = array(
    '#type' => 'textfield',
    '#default_value' => $element['#default_value'],
    '#size' => 3,
    '#maxlength' => 2,
    '#required' => TRUE,
  );
  $element[$name .'_metric'] = array(
    '#type' => 'select',
    '#default_value' => $element['#default_metric'],
    '#options' => array(
      'hours' => t('hours'),
      'mday' => t('days'),
      'mon' => t('months'),
    ),
  );
  return $element;
}

function theme_duration($element) {
  // class="container-inline" makes child widgets align horizontally
  return theme('form_element', $element,
    '<div class="container-inline">'. $element['#children']. '</div>'
  );
}


More information about the development mailing list