Building a form class extending FormBasefor Drupal 8 , 9 , 10 , and 11

Last updated :  

Welcome to the next stage of mastering Drupal's Form API. Having familiarized yourself with the fundamental concepts, it's time to explore how to build a form class by extending FormBase. This approach showcases Drupal's commitment to leveraging object-oriented programming (OOP) principles, enabling greater code organization and reusability.

Understanding FormBase in Drupal

In Drupal, FormBase is an abstract class provided by the core that simplifies form creation through an object-oriented approach. By extending FormBase, you create a custom form class that encapsulates all necessary logic and behavior of your form, including definition, validation, and submission handling, in an organized manner.

Setting Up a Custom Module for Form Development

Before diving into coding, ensure you have a custom module set up. If you haven't created a module yet, follow these steps:

  1. Create a directory in modules/custom within your Drupal installation.
  2. Create a module folder, for example, my_custom_form.
  3. Inside this folder, create a my_custom_form.info.yml file. Here's a basic example:

name: 'My Custom Form'
type: module
description: 'A module to demonstrate a custom form using FormBase.'
package: Custom
core_version_requirement: ^8 || ^9
dependencies: []

    

Creating a Custom Form Class

Now that your module is set up, it's time to create a form class that extends FormBase. Follow these steps:

  1. Create a directory named src/Form within your module directory. This folder will contain your form classes.
  2. Create a new PHP file, e.g., CustomForm.php, inside the src/Form directory.

Here's a basic template for a form class extending FormBase:


namespace Drupal\my_custom_form\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;

class CustomForm extends FormBase {

    /**
     * {@inheritdoc}
     */
    public function getFormId() {
        return 'custom_form_id';
    }

    /**
     * {@inheritdoc}
     */
    public function buildForm(array $form, FormStateInterface $form_state) {
        // Form elements will be defined in this method.
        $form['name'] = [
            '#type' => 'textfield',
            '#title' => $this->t('Your Name'),
            '#required' => TRUE,
        ];

        $form['email'] = [
            '#type' => 'email',
            '#title' => $this->t('Your Email'),
            '#required' => TRUE,
        ];

        $form['submit'] = [
            '#type' => 'submit',
            '#value' => $this->t('Submit'),
        ];

        return $form;
    }

    /**
     * {@inheritdoc}
     */
    public function submitForm(array &$form, FormStateInterface $form_state) {
        \Drupal::messenger()->addMessage($this->t('Hello, @name!', ['@name' => $form_state->getValue('name')]));
    }
}

    

Key Functions Explained

In the custom form class, there are three main methods essential to the form creation process:

getFormId()

This method uniquely identifies your form within Drupal's ecosystem. The form ID is a simple string that Drupal uses to recognize and manage your form, especially when there are multiple forms on a single page.

buildForm()

In this method, you define the form's structure using render arrays as discussed in the previous lesson. The buildForm method is where you'll spend most of your time setting up the form elements, such as text fields, email fields, buttons, etc.

submitForm()

This method handles form submissions. It's where you define business logic that processes form inputs and where you'll likely interact with Drupal's database, configuration, or external services.

Testing Your Form

To test your new form, you need to route it within Drupal. Add a my_custom_form.routing.yml file in the module folder:


my_custom_form.custom_form:
  path: '/custom-form'
  defaults:
    _form: '\Drupal\my_custom_form\Form\CustomForm'
    _title: 'My Custom Form'
  requirements:
    _permission: 'access content'

    

Conclusion

By extending FormBase, you've learned how to organize your form code effectively and leverage object-oriented programming within Drupal. This approach not only promotes cleaner code but also prepares you for more advanced topics in Drupal development.

Next Steps

In our upcoming lesson, we'll explore "Using buildForm() to define form elements" in more detail. You'll discover how to create various form components and deepen your understanding of configuring properties and attributes to enhance your forms' functionality.