function hook_forms

You are here

7 system.api.php hook_forms($form_id, $args)
5 core.php hook_forms()
6 core.php hook_forms($form_id, $args)

Map form_ids to form builder functions.

By default, when drupal_get_form() is called, the system will look for a function with the same name as the form ID, and use that function to build the form. If no such function is found, Drupal calls this hook. Modules implementing this hook can then provide their own instructions for mapping form IDs to constructor functions. As a result, you can easily map multiple form IDs to a single form constructor (referred to as a 'base' form).

Using a base form can help to avoid code duplication, by allowing many similar forms to use the same code base. Another benefit is that it becomes much easier for other modules to apply a general change to the group of forms; hook_form_BASE_FORM_ID_alter() can be used to easily alter multiple forms at once by directly targeting the shared base form.

Two example use cases where base forms may be useful are given below.

First, you can use this hook to tell the form system to use a different function to build certain forms in your module; this is often used to define a form "factory" function that is used to build several similar forms. In this case, your hook implementation will likely ignore all of the input arguments. See node_forms() for an example of this. Note, node_forms() is the hook_forms() implementation; the base form itself is defined in node_form().

Second, you could use this hook to define how to build a form with a dynamically-generated form ID. In this case, you would need to verify that the $form_id input matched your module's format for dynamically-generated form IDs, and if so, act appropriately.

Parameters

$form_id: The unique string identifying the desired form.

$args: An array containing the original arguments provided to drupal_get_form() or drupal_form_submit(). These are always passed to the form builder and do not have to be specified manually in 'callback arguments'.

Return value

An associative array whose keys define form_ids and whose values are an associative array defining the following keys:

  • callback: The name of the form builder function to invoke. This will be used for the base form ID, for example, to target a base form using hook_form_BASE_FORM_ID_alter().
  • callback arguments: (optional) Additional arguments to pass to the function defined in 'callback', which are prepended to $args.
  • wrapper_callback: (optional) The name of a form builder function to invoke before the form builder defined in 'callback' is invoked. This wrapper callback may prepopulate the $form array with form elements, which will then be already contained in the $form that is passed on to the form builder defined in 'callback'. For example, a wrapper callback could setup wizard-alike form buttons that are the same for a variety of forms that belong to the wizard, which all share the same wrapper callback.

Related topics

5 functions implement hook_forms()

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

comment_forms in modules/comment/comment.module
Implements hook_forms().
dashboard_forms in modules/dashboard/dashboard.module
Implements hook_forms().
node_forms in modules/node/node.module
Implements hook_forms().
search_forms in modules/search/search.module
Implements hook_forms().
trigger_forms in modules/trigger/trigger.module
Implements hook_forms().
1 invocation of hook_forms()
drupal_retrieve_form in includes/form.inc
Retrieves the structured array that defines a given form.

File

modules/system/system.api.php, line 1824
Hooks provided by Drupal core and the System module.

Code

function hook_forms($form_id, $args) {
  // Simply reroute the (non-existing) $form_id 'mymodule_first_form' to
  // 'mymodule_main_form'.
  $forms['mymodule_first_form'] = array(
    'callback' => 'mymodule_main_form',
  );

  // Reroute the $form_id and prepend an additional argument that gets passed to
  // the 'mymodule_main_form' form builder function.
  $forms['mymodule_second_form'] = array(
    'callback' => 'mymodule_main_form',
    'callback arguments' => array('some parameter'),
  );

  // Reroute the $form_id, but invoke the form builder function
  // 'mymodule_main_form_wrapper' first, so we can prepopulate the $form array
  // that is passed to the actual form builder 'mymodule_main_form'.
  $forms['mymodule_wrapped_form'] = array(
    'callback' => 'mymodule_main_form',
    'wrapper_callback' => 'mymodule_main_form_wrapper',
  );

  return $forms;
}

Comments

Is there a way to redirect the callback function to another file ? I've tried with 'file' => 'file.path' but didn't work.

This documentation is a bit misleading. Hook_forms() is not a static hook (like hook_menu).

I needed to place the same form multiple times on a page but still be unique so that FAPI would know which one was being submitted.

<?php
  $form
= drupal_get_form("workflow_tab_form_$node->nid", $node, $workflow->wid, $states, $current);
?>

This allows FAPI to set the $form_id to include the node id, thereby making each form seem unique.

The hook looks like this:

<?php
/**
* Implements hook_forms().
*
* Allows the workflow tab form to be repeated multiple times on a page.
* See http://drupal.org/node/1970846.
*/
function workflow_forms($form_id, $args) {
 
$forms = array();

  if (

substr($form_id, 0, 18) == 'workflow_tab_form_') {
   
$forms[$form_id] = array('callback' => 'workflow_tab_form');
  }
  return
$forms;
}
?>

[There is no line break in that if() statement.]