Creating Forms in Drupal

Drupal's Form API is a framework that encompasses the HTTP form handling workflow including displaying a form, validating user input, and handling submitted data. The From API allows module developers to create, validate, and manage custom forms and alter existing ones, ensuring consistent form handling and user interaction across the site.

This course covers the Drupal Form API including; the life cycle of a form, and how to define new form controllers and routes. You will also learn how to add input elements, inject services into form controllers, and provide default values for form elements. Additionally, the course will teach you how to alter existing forms provided by other modules by implementing hook_form_alter(), retrieve and display forms, and theme forms using Twig.

Key topics

Overview of the Form API Understanding the form processing life cycle Defining a new form controller and route Adding input elements to a form Injecting services into a form controller Populating form elements with default values Finding documentation for form element types Altering existing forms provided by other modules

Tutorials in this course
Categories
Drupal 8, 9, and 10
More information

Drupal's Form API is a set of interfaces, utility classes, and conventions that when combined together allow module developers to create forms that collect, validate, and process user-submitted data. The Form API is closely related to the Render API. It uses Render Arrays to define forms, and adds an additional level of workflow and processing to enhance the Render API with some features specific to handling forms.

Given that forms are one of the primary means of interacting with a Drupal site via the UI, understanding how the Form API works is a critical part of learning to develop modules for Drupal. While you may not need to know all the nitty-gritty details, every Drupal module developer is likely to encounter aspects of the Form API at some point. Understanding the basics should be considered required knowledge.

Theme developers are also likely to encounter some aspects of the Form API, as forms are inherently part of the look and feel of a site. Knowing how to make changes to the UX of a form is an important skill.

In this tutorial we'll:

  • Describe what forms are and how they are used in Drupal
  • Explain the relationship between Form API and the Render API
  • List some of the benefits of using the Form API over generic HTML forms

By the end of this tutorial you should have a solid understanding of the role of the Form API in Drupal.

Categories
Drupal 8, 9, and 10
More information

This tutorial will help you understand the complete life cycle of a Drupal form: receiving the request from a browser, displaying a page with a form, rendering the form as HTML, handling the submitted form, validating input, handling errors, and processing data. We'll point out the common places that module developers might want to inject additional functionality into the process. And we'll link to tutorials with more details about each integration point in a form's life cycle.

In this tutorial, we'll:

  • List the steps of the life cycle of a Drupal form.
  • Describe how Drupal determines which form to display, and which form handles an HTTP POST request.
  • Understand the role of FormStateInterface in the life cycle of a form.

By the end of this tutorial, you should have a solid understanding of the life cycle of a form within Drupal.

More information

Each form is defined by a controller, a class that implements the \Drupal\Core\Form\FormInterface. Form controllers declare the unique ID of the form, the $form array that describes the content of the form, how to validate the form, and what to do with the data collected.

In this tutorial we'll:

  • Define a new form controller class
  • Implement the required methods to describe a form
  • Add a route that can be used to access our form

By the end of this tutorial you should be able to define a form that adheres to the FormInterface requirements and know where to find more information about how to further customize your form controller.

Categories
Drupal 8, 9, and 10
More information

Module developers can add new elements to a form by adding their definition to the $form array in the buildForm() method of their controller or via an implementation of hook_form_alter(). Doing so requires knowing the element #type, and details about any element-type-specific properties.

In this tutorial we'll:

  • Determine the element type to use for the HTML input element we want to use
  • Consult the documentation for the two form element types we're using
  • Add a checkbox and a select list to our form via the buildForm() method of our form controller

By the end of this tutorial you'll know how to add new elements to an existing $form array in order to collect additional data from users.

More information

Eventually you'll want to do something with the information your form collects beyond just printing it to the screen. It's generally considered a best practice to keep business logic out of your form controller so that it can be reused. In order to accomplish that you'll generally define your business logic in a service, and then call out to that service from your form controller. Or, you can make use of one of the existing services provided by Drupal core to save data.

In this tutorial we'll:

  • Use dependency injection to inject a service into a form controller
  • Make use of a service injected into a form controller from within the buildForm() and submitForm() methods

By the end of this tutorial you'll understand how to inject one or more services into your form controller and then make use of them.

More information

Forms are used for both collecting new data, and editing existing data. In order to allow users to modify existing data you need to pre-populate the elements on the form with the data you previously stored.

In this tutorial we'll look at the ways in which forms can be pre-populated with existing data, including:

  • Providing default values for form elements which a user can edit with the #default_value property
  • The differences between the #value and #default_value properties

By the end of this tutorial you should know how to populate forms using existing data.

Categories
Drupal 8, 9, and 10
More information

Drupal core provides a couple dozen different input #type elements that can be added to forms. This includes one for every standard HTML5 input element, and some Drupal-specific ones that encapsulate more complex interactions like uploading files. But how can you know what elements exist? Where do you find information about what Render API properties each element uses?

In this tutorial we'll:

  • Define what FormElements are and how they relate to the Render API
  • Find a list of all available input element types, additional documentation and usage examples
  • See examples of the most common element types

By the end of this tutorial you should be able to discover the different types of elements you can add to a $form array and find usage examples for each.

More information

You'll often need to make minor, or major, alterations to an existing form provided by another module. The Form API allows you to alter any existing form through a series of hooks without having to change the existing module's code at all. This is probably one of the most powerful features of the Drupal Form API. Knowing how to implement and leverage hook_form_alter() and its variations is an essential skill for any module developer.

In this tutorial we'll:

  • Learn how to implement hook_form_alter() and hook_form_FORM_ID_alter() in a module
  • Modify existing elements, or add new elements, to a form provided by another module
  • Understand how to add new validation and submission handlers when altering an existing form

By the end of this tutorial you should know how to alter almost everything about the way any form in Drupal works without having to hack the module that provides the form.

Categories
Drupal 8, 9, and 10
More information

Forms can be displayed as the main content of a route or by using the form_builder service to retrieve and display a form directly. Which one you choose will depend on where on the page you want the form to appear.

In this tutorial we'll:

  • Go over the two different ways a form can be retrieved and displayed
  • Demonstrate how to display a form inside a custom block using the form_builder service

By the end of this tutorial you'll know how to retrieve a form and have it rendered anywhere on the page.

More information

By default, individual forms in Drupal are not output using Twig template files. It's possible to associate a form with a Twig template file by creating a new theme hook, and then referencing that theme hook from the $form array that defines the form. Doing so allows theme developers to customize the layout of the elements in the form using HTML and CSS.

This is useful when you want to change the layout of the entire form. For example, putting the elements into 2 columns. If you want to change individual elements in the form, you can often do so by overriding element specific Twig template files.

In this tutorial, we'll:

  • Learn how to create a new theme hook that can be used to theme an element in a render array.
  • Associate the $form we want to theme with the new theme hook we created.
  • Create a Twig template file for the theme hook that will allow us to lay out the form elements using custom HTML.

By the end of this tutorial, you should be able to associate a Twig template file with any form in Drupal, so that you can customize its layout using HTML and CSS.

This course appears in the following guides:
Module Development
Learn to use Drupal's Form API to define, validate, and process forms in modules and themes.

Develop Forms in Modules