Form generation

Same name and namespace in other branches
  1. 7.x includes/ \form_api
  2. 9 core/core.api.php \form_api
  3. 8.9.x core/core.api.php \form_api
  4. 10 core/core.api.php \form_api

Describes how to generate and manipulate forms and process form submissions.

Drupal provides a Form API in order to achieve consistency in its form processing and presentation, while simplifying code and reducing the amount of HTML that must be explicitly generated by a module.

Creating forms

Forms are defined as classes that implement the \Drupal\Core\Form\FormInterface and are built using the \Drupal\Core\Form\FormBuilder class. Drupal provides a couple of utility classes that can be extended as a starting point for most basic forms, the most commonly used of which is \Drupal\Core\Form\FormBase. FormBuilder handles the low level processing of forms such as rendering the necessary HTML, initial processing of incoming $_POST data, and delegating to your implementation of FormInterface for validation and processing of submitted data.

Here is an example of a Form class:

namespace Drupal\my_module\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
class ExampleForm extends FormBase {
    public function getFormId() {
        // Unique ID of the form.
        return 'example_form';
    public function buildForm(array $form, FormStateInterface $form_state) {
        // Create a $form API array.
        $form['phone_number'] = [
            '#type' => 'tel',
            '#title' => $this->t('Your phone number'),
        $form['save'] = [
            '#type' => 'submit',
            '#value' => $this->t('Save'),
        return $form;
    public function validateForm(array &$form, FormStateInterface $form_state) {
        // Validate submitted form data.
    public function submitForm(array &$form, FormStateInterface $form_state) {
        // Handle submitted form data.


Retrieving and displaying forms

\Drupal::formBuilder()->getForm() should be used to handle retrieving, processing, and displaying a rendered HTML form. Given the ExampleForm defined above, \Drupal::formBuilder()->getForm('Drupal\my_module\Form\ExampleForm') would return the rendered HTML of the form defined by ExampleForm::buildForm(), or call the validateForm() and submitForm(), methods depending on the current processing state.

The argument to \Drupal::formBuilder()->getForm() is the name of a class that implements FormInterface. Any additional arguments passed to the getForm() method will be passed along as additional arguments to the ExampleForm::buildForm() method.

For example:

$extra = '612-123-4567';
$form = \Drupal::formBuilder()->getForm('Drupal\my_module\Form\ExampleForm', $extra);
public function buildForm(array $form, FormStateInterface $form_state, $extra = NULL)
  $form['phone_number'] = [
    '#type' => 'tel',
    '#title' => $this->t('Your phone number'),
    '#value' => $extra,
  return $form;

Alternatively, forms can be built directly via the routing system which will take care of calling \Drupal::formBuilder()->getForm(). The following example demonstrates the use of a routing.yml file to display a form at the given route.

  path: '/example-form'
    _title: 'Example form'
    _form: '\Drupal\my_module\Form\ExampleForm'

The $form argument to form-related functions is a specialized render array containing the elements and properties of the form. For more about render arrays, see the Render API topic. For more detailed explanations of the Form API workflow, see the Form API documentation section. In addition, there is a set of Form API tutorials in the Examples for Developers project.

In the form builder, validation, submission, and other form methods, $form_state is the primary influence on the processing of the form and is passed to most methods, so they can use it to communicate with the form system and each other. $form_state is an object that implements \Drupal\Core\Form\FormStateInterface.


core/core.api.php, line 1680


Title Sort descending File name Summary
hook_form_alter core/lib/Drupal/Core/Form/form.api.php Perform alterations before a form is rendered.
hook_form_BASE_FORM_ID_alter core/lib/Drupal/Core/Form/form.api.php Provide a form-specific alteration for shared ('base') forms.
hook_form_FORM_ID_alter core/lib/Drupal/Core/Form/form.api.php Provide a form-specific alteration instead of the global hook_form_alter().
RedirectDestinationInterface::getAsArray core/lib/Drupal/Core/Routing/RedirectDestinationInterface.php Prepares a 'destination' URL query parameter for use with \Drupal\Core\Url.


Title Sort descending File name Summary
FormBase core/lib/Drupal/Core/Form/FormBase.php Provides a base class for forms.
FormBuilder core/lib/Drupal/Core/Form/FormBuilder.php Provides form building and processing.
FormCache core/lib/Drupal/Core/Form/FormCache.php Encapsulates the caching of a form and its form state.
FormHelper core/lib/Drupal/Core/Form/FormHelper.php Provides helpers to operate on forms.


Title Sort descending File name Summary
FormInterface core/lib/Drupal/Core/Form/FormInterface.php Provides an interface for a Form.
FormStateInterface core/lib/Drupal/Core/Form/FormStateInterface.php Provides an interface for an object containing the current state of a form.


Title Sort descending File name Summary
FormStateValuesTrait core/lib/Drupal/Core/Form/FormStateValuesTrait.php Provides methods to manage form state values.

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.