Displaying a Form as a Block

Objectives
  • Learn how to display a form as a block.
Prerequisites
  • Created a form.
  • Having made that form available on its own page by creating a route.

You can display forms on their own page via a route, but that's not the only way to display forms. You can also embed them in page or block content, or create a block that displays only the form and nothing else.

To make a form available as a block:

  • Create a new block class
  • Inside its build() method, retrieve the form as a render array and return it.

Let's put that into practice:

Activity

  • Create a new block named ColourFormBlock.
  • Have the build() method return a basic message like "This is where the form will be displayed."

→ ensure your block works correctly by placing it in the sidebar and checking the result.

Hide hints
show hints

Rendering a form instead of content

You can use the formBuilder service, available via the service container, to retrieve and build forms:

$form = \Drupal::formBuilder()->getForm('Drupal\my_module\Form\MyFormClass');

If you look at BuildForm::getForm()'s documentation, you'll see it retrieves the form with the given class name, builds it, and returns the form as a render array.

Activity

  • Update your ColourFormBlock::build() method:
    • Retrieve your form using the full form class name.
    • Instead of returning the $build render array with your message, return your $form render array.

1. Why does returning $form instead of $build work too?

\Drupal::formBuilder()->getForm() retrieves the form definition of a given form class, builds the form, and returns it as a render array, ready for display.

Your block's build() method still returns a render array, as it should. It just happens to be a render array that contains a form, rather than a render array you constructed yourself showing a short message.

2. What's the full name of my form class?

The full name of your form class is the namespace + the class name:

Drupal\my_form_demo\Form\ColourForm

→ This is the same class name you used for the_form property of your my_form_demo.colour route.

Hide hints
show hints

If everything went well, you should have the following result:

Try using the form. Your custom validation and redirection should still work.

Summary

  • You can make a form available as a block by creating a block class that implements a build() method that returns that form as a render array.
  • You can retrieve a form as a render array via \Drupal::buildForm().