Altering a Form

Last updated on
6 November 2024

In order to alter an existing form, all you have to do is just to create an Annotation Plugin in your [modulename]/src/Plugin/FormAlter folder.

You can alter a form by using both form_id and base_form_id properties. Plugins using the base_form_id property will be executed before those using the form_id. If you want, you can use both properties in the same Plugin. However, please do it only if you really know what you're doing.

Form Alter via base_form_id

<?php

namespace Drupal\my_module\Plugin\FormAlter;

use Drupal\Core\Form\FormStateInterface;
use Drupal\pluginformalter\Annotation\FormAlter;
use Drupal\pluginformalter\Plugin\FormAlterBase;

/**
 * Class MyModuleBaseFormAlter.
 *
 * @FormAlter(
 *   id = "my_module_base_form_alter",
 *   label = @Translation("Altering every node edit form."),
 *   base_form_id = {
 *    "node_form"
 *   },
 * )
 *
 * @package Drupal\my_module\Plugin\FormAlter
 */
class MyModuleBaseFormAlter extends FormAlterBase {

  /**
   * {@inheritdoc}
   */
  public function formAlter(array &$form, FormStateInterface $form_state, $form_id) {
    // It will be shown on every node edit form.
    $form['#prefix'] = '<h2>Edit form</h2>';
  }

}
?>

Form Alter via form_id 

<?php

/**
 * Class MyModuleFormAlter.
 *
 * @FormAlter(
 *   id = "my_module_form_alter",
 *   label = @Translation("Altering basic page and article edit forms."),
 *   form_id = {
 *    "node_*_edit_form"
 *   },
 * )
 *
 * @package Drupal\my_module\Plugin\FormAlter
 */
class MyModuleFormAlter extends FormAlterBase {

  /**
   * {@inheritdoc}
   */
  public function formAlter(array &$form, FormStateInterface $form_state, $form_id) {
    // do something here, for example add submit handler.
    $submit_handler = __CLASS__ . '::formSubmit';
    array_unshift($form['actions']['submit']['#submit'], $submit_handler);
  }

  /**
   * Custom form submit.
   */
  public static function formSubmit($form, FormStateInterface $form_state) {
  }

}
?>

As you can see in this example we're using wildcards inside our form_id definition. By using "node_*_edit_form" we're gonna alter both "node_page_edit_form" and "node_article_edit_form" (in a context where Page and Article are the only content types we got so far).

How to change form alter priority

When you start using this module it may happen that the form you're trying to alter is already getting altered by other modules. If you need Form Alter as Plugin to run its alters after any other module you can achieve this by adding this snippet to your .module file:

function my_module_module_implements_alter(&$implementations, $hook) {
  if ($hook == 'form_alter') {
    $group = $implementations['pluginformalter'];
    unset($implementations['pluginformalter']);
    $implementations['pluginformalter'] = $group;
  }
}

Help improve this page

Page status: No known problems

You can: