Transitioning to Drupal 8: Admin forms

This is part of the series to help you transition to Drupal 8 module development by comparing it with Drupal 7. This week, we are going to look at admin forms.

As an example, we will look at a very simple admin form that has one field, a textarea. The form will allow site editors and administrators to change a message. That message can be used elsewhere in the system, such as displaying it to users when they log in.

In Drupal 7, you create a form using the Form API and define it as an array. In Drupal 8, you need to define a class and like Drupal 7, you define the form as an array.

Creating an admin form in Drupal 7

This form definition could live in the .module file or in a file called welcome.admin.inc (replace "welcome" with the name of your module) in your custom module.

<?php
/**
 * Implements hook_form().
 * Admin form to configurable welcome message 
 */
function welcome_admin_form($form, &$form_state) {
  $form['welcome_message'] = array(
    '#type' => 'textarea',
    '#title' => t('Welcome message'), 
    '#description' => t('Welcome message display to users when they login'),
    '#default_value' => variable_get('welcome_message', 'welcome'),

  );

  return system_settings_form($form);
}

Forms in Drupal 7 are defined as an array, which Drupal will then use to render as a HTML form.

Using system_settings_form()

In the return statement, $form is passed through another function, system_settings_form(). This handy function takes care of common tasks that are needed for any admin form, such as submit buttons and saving form data to the database. It will save it to the variables table. If you are defining a form that is not an admin form, then you would add the submit buttons and handle saving form data yourself.

Using variable_get()

The default value uses variable_get() to retrieve the data from the variables table.

variable_get() is a built-in Drupal function that will get any variable. The first argument is the variable name. The second is a default value, which will be used if the variable does not yet exist in the database. The default value is required, so you need to add something. I have used the word "welcome".

Learn more about admin forms in Drupal 7.

Creating an admin form in Drupal 8

The form definition in Drupal 8 will seem more complicated at first, but there are a lot of similarities with how it is done in Drupal 7.

A form with the same fields as the Drupal 7 example would look like this:

<?php

/**
 * @file
 * Contains Drupal\welcome\Form\MessagesForm.
 */

namespace Drupal\welcome\Form;

use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;

class MessagesForm extends ConfigFormBase {
  /**
   * {@inheritdoc}
   */
  protected function getEditableConfigNames() {
    return array(
      'welcome.adminsettings',
    );
  }

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

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $config = $this->config('welcome.adminsettings');

    $form['welcome_message'] = array(
      '#type' => 'textarea',
      '#title' => $this->t('Welcome message'),
      '#description' => $this->t('Welcome message display to users when they login'),
      '#default_value' => $config->get('welcome_message'),
    );
    return parent::buildForm($form, $form_state);
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    parent::submitForm($form, $form_state);

    $this->config('welcome.adminsettings')
      ->set('welcome_message', $form_state->getValue('welcome_message'))
      ->save();
  }
}

This example is in a file called MessagesForm.php which is in a folder called Form in a custom module.

When creating a simple configuration form, you should extend DrupalCoreFormConfigFormBase. ConfigFormBase is a base class that is used to implement system configuration forms. In other cases, you can extend the more generic FormBase class.

The following methods are used:

  • getEditableConfigNames() - gets the configuration name
  • getFormId() - returns the form’s unique ID
  • buildForm() - returns the form array
  • validateForm() - validates the form
  • submitForm() - processes the form submission

Form field array

The form is defined as an array, just like it is in Drupal 7.

Drupal 8 form field array:

$config = $this->config('welcome.adminsettings');
$form['welcome_message'] = array(
  '#type' => 'textarea',
  '#title' => $this->t('Welcome message'),
  '#description' => $this->t('Welcome message display to users when they login'),
  '#default_value' => $config->get('welcome_message'),
);

Drupal 7 form field array:

$form['welcome_message'] = array(
    '#type' => 'textarea',
    '#title' => t('Welcome message'), 
    '#description' => t('Welcome message display to users when they login'),
    '#default_value' => variable_get('welcome_message', 'welcome'),
  );

As you can see, the forms are almost identical. The main difference is the default value. Where Drupal 7 uses variable_get() to get the saved variable value from the database, Drupal 8 uses $config->get. Drupal 8 uses configuration objects instead of variables for simple admin forms like this. This code calls the get() method with the name of a configuration object property to get, which is welcome_message.

$config = $this->config('welcome.adminsettings');

This initialises the config variable. ‘welcome.adminsettings' is the module's configuration name, so this will load the admin settings.  

'#default_value' => $config->get('welcome_message'),

The default value is returned from the configuration object. It calls the get() method with the name of the property to get, which is welcome_message.

Saving the data

As mentioned above, Drupal 8 uses configuration objects to save the data.

The submitForm() method is responsible for saving the form data when the form is submitted.

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    parent::submitForm($form, $form_state);

    $this->config('welcome.adminsettings')
      ->set('welcome_message', $form_state->getValue('welcome_message'))
      ->save();
  }

The configuration item is saved in the submitForm() method. Let’s break this down line by line:

  • $this is the admin settings form class.
  • -> is an object operator
  • config('welcome.adminsettings’): 'welcome.adminsettings' is the name of the module's configuration.
  • ->set('welcome_message', $form_state->getValue('welcome_message’)): here it is setting ‘welcome_message’ and gets the values from the form state.
  • ->save: save the form data.

In Drupal 7, you don't need a submit function for a simple admin form because system_settings_form() will take care of submitting and saving the form data.

Next steps

In the next few weeks, I will share a complete walk through of creating an admin form in Drupal 8, including the route, menu item and a look at how the data is saved in the database. If you don't want to miss out on that, jump on my newsletter


Master Drupal Module Development

Don't struggle to master module development. Action packed lessons where you will work along building your own real world modules.

"..the must have drupal developers book"

Find out more


Add new comment