Drupal 8 Module Development, Part 2: Forms

Drupal 8 Module Development, Part 2: Forms

Like all Drupal 8 module development, creating forms isn't quite as straight forward as it has been in the past using the hook system. Symfony has changed the way that forms get created and called, adding a layer of complexity with the move to object-oriented code. As far as the actual form API, several HTML5 form elements have been introduced, but in general it should be a pretty easy transition for most people.

Basic Forms

We'll start by creating a very simple form that doesn't have any bells and whistles.

Step 1: Create your form controller

Start by creating your controller file, modules/foobar/lib/Drupal/foobar/Form/FoobarForm.php, with the following contents:

There are a few things to make note of here:

  • The most basic type of Drupal form always implements the FormInterface interface which provides a basic "template" for what is required in your form class definition. This means that getFormID, buildForm, validateForm, and submitForm are all required methods within your class.
  • Form classes can, and should, be utilized to provide additional functionality to your form. In other words, place any "extra" code that needs to be executed by your form within the same class, rather than in your .module file or elsewhere (this is a basic principle of object-oriented programming).
  • buildForm returns a Form API form array, and the validateForm, and submitForm methods both function exactly as the submit and validate handlers do in Drupal 7.

Step 2: Create your route

You'll need to create a route for your new form controller. Inside foobar.routing.yml add the following code:

Notice that we're using the _form parameter instead of _content to define which controller to use.

Don't forget to register your menu item using hook_menu() once you're done!

Arbitrarily rendering forms

Controllers and routers are great, but what if I don't want to render a form on a page?

drupal_get_form() used to be the function you needed any time you wanted to display a form anywhere. Now that we're using controllers and routers, drupal_get_form() is no longer necessary for displaying forms as pages. However, it is still needed to render forms inside things like blocks…

Extending Form Types

There are a number of form types in core Drupal that may already include some or all of the fields and functionality that you're needing to create. Part of the beauty of object-oriented code is that you can simply extend these form types rather than reinventing the wheel each time. This adds a layer of consistency that you may not have any other way.

Let's assume you want to create a basic admin configuration form with the Save configuration button at the bottom. Typically, you would use system_settings_form() in your form definition to add additional administrative functionality to a form. However, the same thing can be achieved simply by extending the SystemConfigFormBase class in Drupal 8.

This particular form type, SystemConfigFormBase, comes from the System module in core.

Including but not limited to…

Here's a short list of some of the extendable form types in core:

  1. SystemConfigFormBase
  2. ConfirmFormBase
  3. BulkFormBase
  4. FieldInstanceFormBase
  5. ViewsFormBase

Fork this project on GitHub