ConfirmFormBase To Confirm an Action

Last updated on
26 February 2024

Confirmation forms are the recommended way to prompt a user for confirmation of an action. For example, when you delete a Node and Drupal presents a confirmation page with the message "Are you sure you wan't to delete this node?" and the option to continue or go back. As with many forms, it all begins with a route. 

Routes

Within a module's *.routing.yml file, create a route to the form. In many cases, it will be desirable to pass a parameter from the path to the confirmation form, as would be the case if some kind of content was being deleted. This can be seen in the following example:

example_module.delete:
  path: '/example/{id}/delete'
  defaults:
    _form: '\Drupal\example_module\Form\ConfirmDeleteForm'
    _title: 'Confirm Deletion'
  requirements:
    _permission: 'administer site configuration'
    id: ^\d+$

The value of id is passed to the form's buildForm() function via a parameter appended to the standard parameter list. A regex to only allow numeric ids to be passed has been applied under the 'requirements' section.

Note: The route parameters are user supplied content and is therefore NOT SAFE. The regex above guarantees that only numerics are passed along but other parameters will likely need to be sanitized or verified in some way to ensure malicious content doesn't get passed along.

ConfirmFormBase

Construct a new form in "example_module/src/Form/ConfirmDeleteForm.php" that extends ConfirmFormBase and implements ConfirmFormInterface. At minimum, the following four functions from ConfirmFormInterface need to get implemented:

  • public function submitForm(array &$form, FormStateInterface $form_state);
  • public function getFormId();
  • public function getCancelUrl();
  • public function getQuestion();

To see what else you can implement check the ConfirmFormInterface API document.

In order to get the route parameter for use within the form you will need to create a field in the class to store it and you will need to implement buildForm() with an additional parameter for the route parameter.

Example

File example_module/src/Form/ConfirmDeleteForm.php:

<?php

namespace Drupal\example_module\Form;

use Drupal\Core\Form\ConfirmFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;

/**
 * Defines a confirmation form to confirm deletion of something by id.
 */
class ConfirmDeleteForm extends ConfirmFormBase {

  /**
   * ID of the item to delete.
   *
   * @var int
   */
  protected $id;

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state, string $id = NULL) {
    $this->id = $id;
    return parent::buildForm($form, $form_state);
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    // @todo: Do the deletion.
  }

  /**
   * {@inheritdoc}
   */
  public function getFormId() : string {
    return "confirm_delete_form";
  }

  /**
   * {@inheritdoc}
   */
  public function getCancelUrl() {
    return new Url('example_module.another_path');
  }

  /**
   * {@inheritdoc}
   */
  public function getQuestion() {
    return $this->t('Do you want to delete %id?', ['%id' => $this->id]);
  }

}

This example is fairly minimalistic and there are many ways it could be improved. Within Drupal, using the Bartik theme, the result would look like this:

 

Help improve this page

Page status: No known problems

You can: