4.7.x core.php hook_elements()
5.x core.php hook_elements()
6.x core.php hook_elements()

Allows modules to declare their own Forms API element types and specify their default values.

This hook allows modules to declare their own form element types and to specify their default values. The values returned by this hook will be merged with the elements returned by hook_form() implementations and so can return defaults for any Form APIs keys in addition to those explicitly mentioned below.

Each of the form element types defined by this hook is assumed to have a matching theme function, e.g. theme_elementtype(), which should be registered with hook_theme() as normal.

For more information about custom element types see the explanation at http://drupal.org/node/169815 .

Return value

An associative array describing the element types being defined. The array contains a sub-array for each element type, with the machine-readable type name as the key. Each sub-array has a number of possible attributes:

  • "#input": boolean indicating whether or not this element carries a value (even if it's hidden).
  • "#process": array of callback functions taking $element, $edit, $form_state, and $complete_form.
  • "#after_build": array of callback functions taking $element and $form_state.
  • "#validate": array of callback functions taking $form and $form_state.
  • "#element_validate": array of callback functions taking $element and $form_state.
  • "#pre_render": array of callback functions taking $element and $form_state.
  • "#post_render": array of callback functions taking $element and $form_state.
  • "#submit": array of callback functions taking $form and $form_state.

Related topics

3 functions implement hook_elements()

Note: this list is generated by pattern matching, so it may include some functions that are not actually implementations of this hook.

format_xml_elements in includes/common.inc
Format XML elements.
system_elements in modules/system/system.module
Implementation of hook_elements().
user_elements in modules/user/user.module
Implementation of hook_elements().


developer/hooks/core.php, line 489
These are the hooks that are invoked by the Drupal core.


function hook_elements() {
  $type['filter_format'] = array(
    '#input' => TRUE,
  return $type;


mikl’s picture

Remember that if you create your own element, you will need to provide a theme callback for it, at minimum something like this:

function theme_myfancyelement($element) {
  return $element['#children'];

Also, remember to register your theming function with hook_theme().

mavimo’s picture

When you theme your element please don't return element, but:

return drupal_render($element);
crea’s picture

Please note, that you should not use drupal_render($element) inside a theme function for $element. Drupal_render() will invoke theme('theme_your_element') and you will have eternal recursion. Just spent several hours debugging this.

Example posted by someone (now removed) at http://drupal.org/node/169815 :

function theme_example_field($element) {
  // Do something to the element here.
  return drupal_render($element);

is absolutely WRONG.

rfay’s picture

See the entry in the module upgrade guide for how hook_elements() became hook_element_info() in Drupal. 7.

wildpeaks’s picture

"#pre_render": array of callback functions taking $element and $form_state.

Unless I'm mistaken, this is innacurate: the callback functions receive only a single parameter ($element).

jaxxed’s picture

The array passed per element contains the default settings for what is passed to the drupal_render method (common.inc:2916 in D6.recent.) These elements can then be overloaded later when the element is instantiated (in your form function) etc.
Any attribute in the hook_element array item can be treated as something that would be in your form array element, that would be passed to the drupal_render method. This is why the keys in this array start with a '#'.

Maybe you can do really funky things here like define children elements etc. If your PHP is decent, you can see how drupal_render works in the include.

#pre render function are passed only the drupal_render argument, which is refered to as $elements (because it can handle arrays of elements as well.)

[edit - added processing]
On The processing side, the #process and #submit functions are used in the form system to pass to drupal_process_form() in form.inc, which does magic with it? If I figure that side out, I'll edit this comment again.

[edit - figured out the processing]

Ok so #process is/are run everytime the form is rendered, letting you change the form tree right before the value is set for the element, whereas #submit sets a 'submit_handler' for the element (only if the form has just been submitted)
This is all in _form_builder_handle_input_element()

ibnkhaldun’s picture

Are there a complete list of useful attributes to declare an element type?
I spent too many hours looking for...

I was reading some samples and the attributes they use are others than the reported here!
Do you really hope somebody can learn to write his own code with a semi-documented info as source?

I think this is not a collaborative way to share knowledge.

RSTaylor’s picture

Note that the #submit callback is not called for custom elements, it only applies to some of the standard elements. For validation, you can use #element_validate instead of #validate for custom elements. But there is no #element_submit, so if you actually need logic on submit (that applies to all elements of the type, regardless of what form they're on), then you need to find another way to hook in and add the submit callback.

#submit documentation

franck0015’s picture

Note that that submit handler in #submit is only called if the element is a button
Someone investigated : https://drupal.org/node/344233

The documentation should mention this.