Settings Form

Last updated on
8 January 2024

Everything's pretty neat so far, but how do we add some flexibility to our module? With some settings forms, of course.

/src/Form/LoremIpsumForm.php

<?php

namespace Drupal\loremipsum\Form;

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

/**
 * Module settings form.
 */
class LoremIpsumForm extends ConfigFormBase {

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

We begin our settings file extending ConfigFormBase. The LoremIpsumForm class is the one referenced in the routing.yml file:

loremipsum.form:
  path: '/admin/config/development/loremipsum'
  defaults:
    _title: 'LoremIpsum settings'
    _form: '\Drupal\loremipsum\Form\LoremIpsumForm'
  requirements:
    _permission: 'administer loremipsum'

The Build method

Next is the method that actually builds the settings form:

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    // Form constructor.
    $form = parent::buildForm($form, $form_state);
    // Default settings.
    $config = $this->config('loremipsum.settings');

The $config variable is where we store our current settings.

Fields

Then we define our form fields and return the form:

    // Page title field
    $form['page_title'] = [
      '#type' => 'textfield',
      '#title' => t('Lorem ipsum generator page title:'),
      '#default_value' => $config->get('loremipsum.page_title'),
      '#description' => $this->t('Give your lorem ipsum generator page a title.'),
    ];
    // Source text field
    $form['source_text'] = [
      '#type' => 'textarea',
      '#title' => t('Source text for lorem ipsum generation:'),
      '#default_value' => $config->get('loremipsum.source_text'),
      '#description' => $this->t('Write one sentence per line. Those sentences will be used to generate random text.'),
    ];

    return $form;
  }

Validation

Before submitting a form, it's good practice to validate it. This is the method responsible for validation:

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state) {
    if ($form_state->getValue('page_title') == NULL) {
      $form_state->setErrorByName('page_title', t('Please enter a valid Page title.'));
    }
    if ($form_state->getValue('source_text') == NULL) {
      $form_state->setErrorByName('source_text', t('Please enter at least one line of text for your generator.'));
    }
  }

Submission

Validated data is ready to be submitted for various ends - in our case, being saved to the database.

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $config = $this->config('loremipsum.settings');
    $config->set('loremipsum.source_text', $form_state->getValue('source_text'));
    $config->set('loremipsum.page_title', $form_state->getValue('page_title'));
    $config->save();
    return parent::submitForm($form, $form_state);
  }

Getting editable config names

This method takes care of the namespace used for saving data in the DB.

  /**
   * {@inheritdoc}
   */
  protected function getEditableConfigNames() {
    return [
      'loremipsum.settings',
    ];
  }

See Introduction to Form API for more info.

In the next section we'll dive into the Plugin System when we define a Block, and that will come with its own Form.

Help improve this page

Page status: No known problems

You can: