Drupal Forms API02/13/2017

In brief
Set the route
Create form class
Initialize the form state
Put it to work!

This post shares insights related to the Drupal Form API. Hope it helps

Set the route

We need a location for the form. In your module, create modulename.routing.yml. For the form location, you should write:

  path: '/admin/structure/slide/add'
    _permission: 'add slide entities'

The permission field should come from modulename.permissions.yml. There should be a block that look's like this:

add slide entities:
  title: 'Create new Slide entities'

Create form class

This can be handled from the console. You want a class located in src/Form/[name]Form.php. The class should be Drupal\modulename\Form. It should inherit a form class like the following:


The form class needs a public function buildForm. The buildForm method takes two arguments array $form and FormStateInterface $form_state. When the console is used to generate a form class, it generates the buildForm method, and calls the parent buildForm method. That body needs to be cleared and attributes need to be added to the $form array. The attributes need to be set to the input field information.

$form['slide_name'] = [
  '#type' => 'textfield',
  '#title' => $this->t('Slide Title')

$form['slide_img'] = [
  '#title' => t('Slide Image'),
  '#type' => 'managed_file',
  '#upload_location' => 'public://slider_images/',

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

At the end of the method, return the form:

return $form;

Initialize the form state

At the beginning of the buildForm method, add this line:

if (!$form_state->has('entity_form_initialized')) {

This is something that I didn't do and it took me a very long time to figure out why I was having trouble. I would submit my form and I would just get an error. The error is in the block below. I got it from the nginx error log.

2017/02/16 22:25:55 [error] 1659#0: *27 FastCGI sent in stderr: "PHP message: PHP Fatal error:  Call to a member function extractFormValues() on null in /drupal/core/lib/Drupal/Core/Entity/ContentEntityForm.php on line 223
PHP message: PHP Stack trace:
PHP message: PHP   1. {main}() /drupal/index.php:0
PHP message: PHP   2. Drupal\Core\DrupalKernel->handle() /drupal/index.php:19
PHP message: PHP   3. Stack\StackedHttpKernel->handle() /drupal/core/lib/Drupal/Core/DrupalKernel.php:652
PHP message: PHP   4. Drupal\Core\StackMiddleware\NegotiationMiddleware->handle() /drupal/vendor/stack/builder/src/Stack/StackedHttpKernel.php:23
PHP message: PHP   5. Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle() /drupal/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php:50
PHP message: PHP   6. Drupal\page_cache\StackMiddleware\PageCache->handle() /drupal/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php:47
PHP message: PHP   7. Drupal\page_cache\StackMiddleware\PageCache->pass() /drupal/core/modules/page_cache/src/StackMiddleware/PageCache.php:78
PHP message: PHP   8. Drupal\Core\StackMiddleware\KernelPreHandle->handle() /drupal/core/modules/page_cache/src/StackMiddleware/PageCache.php:99
PHP message: PHP   9. Drupal\Core\StackMiddleware\Session->handle() /drupal/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php:47
PHP message: PHP  10. Symfony\Component\HttpKernel\HttpKernel->handle() /drupal/core/lib/Drupal/Core/StackMiddleware/Session.php:57
PHP message: PHP  11. Symfony\Component\HttpKernel\HttpKernel->handleRaw() /drupal/vendor/symfony/http-kernel/HttpKernel.php:64
PHP message: PHP  12. call_user_func_array:{/drupal/vendor/symfony/http-kernel/HttpKernel.php:144}() /drupal/vendor/symfony/http-kernel/HttpKernel.php:144
PHP message: PHP  13. Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() /drupal/vendor/symfony/http-kernel/HttpKernel.php:144
PHP message: PHP  14. Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapp
2017/02/16 22:25:55 [error] 1659#0: *27 FastCGI sent in stderr: "ssage: PHP  28. Drupal\Core\Entity\ContentEntityForm->copyFormValuesToEntity() /drupal/core/lib/Drupal/Core/Entity/EntityForm.php:291" while reading response header from upstream, client:, server: drupal.local, request: "POST /admin/structure/slide/add HTTP/1.1", upstream: "fastcgi://unix:/var/run/php5-fpm.sock:", host: "", referrer: ""

Do Something with the submitted data

After all that is done, something has to happen with the data. The form class needs a submitForm method as follows:

public function submitForm(array &$form, FormStateInterface $form_state) {
  $this->processData($form['slide_name']['#value'], $form['slide_img']['#files']);