logo

Extra Block Types (EBT) - Neue Erfahrung im Layout Builder❗

Extra Block Types (EBT) - gestylte, anpassbare Blocktypen: Diashows, Registerkarten, Karten, Akkordeons und viele andere. Eingebaute Einstellungen für Hintergrund, DOM Box, Javascript Plugins. Erleben Sie die Zukunft der Layouterstellung schon heute.

Demo EBT-Module EBT-Module herunterladen

❗Extra Absatztypen (EPT) - Erfahrung mit neuen Absätzen

Extra Paragraph Types (EPT) - analoger, auf Absätzen basierender Satz von Modulen.

Demo EPT-Module EPT-Module herunterladen

Scroll
27/05/2025, by Ivan

In diesem Artikel vertiefen wir die Form API in Drupal 8 und erstellen ein mehrstufiges Formular. Wir haben bereits ein übliches Konfigurationsformular für das Modul erstellt; ein mehrstufiges Formular wird ähnlich erstellt, indem $form_state verwendet wird, um Daten zwischen den Formularschritten zu speichern.

Code-Beispiele finden Sie auf GitHub:

https://github.com/levmyshkin/drupalbook8

Für ein mehrstufiges Formular müssen Sie eine Formular-Klasse anlegen:

/modules/custom/drupalbook/src/Form/MultiStepForm.php

<?php

namespace Drupal\drupalbook\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;

class MultiStepForm extends FormBase {

  protected $step = 1;

  public function getFormID() {
    return 'multi_step_form';
  }

  public function buildForm(array $form, FormStateInterface $form_state) {
    // Wrapper-Div für AJAX-Updates
    $form['#prefix'] = '<div id="ajax_form_multistep_form">';
    $form['#suffix'] = '</div>';

    if ($this->step == 1) {
      $form['message-step'] = [
        '#markup' => '<div class="step">' . $this->t('Step 1 of 2') . '</div>',
      ];
      $form['message-title'] = [
        '#markup' => '<h2>' . $this->t('Who are you?') . '</h2>',
      ];
      $form['first_name'] = [
        '#type' => 'textfield',
        '#title' => $this->t('First name'),
        '#placeholder' => $this->t('First name'),
        '#required' => TRUE,
      ];
      $form['last_name'] = [
        '#type' => 'textfield',
        '#title' => $this->t('Last name'),
        '#placeholder' => $this->t('Last name'),
        '#required' => TRUE,
      ];
    }

    if ($this->step == 2) {
      $form['message-step'] = [
        '#markup' => '<div class="step">' . $this->t('Step 2 of 2') . '</div>',
      ];
      $form['message-title'] = [
        '#markup' => '<h2>' . $this->t('Please enter your contact details below:') . '</h2>',
      ];
      $form['phone'] = [
        '#type' => 'textfield',
        '#title' => $this->t('Phone'),
        '#placeholder' => $this->t('Phone'),
        '#required' => TRUE,
      ];
      $form['email'] = [
        '#type' => 'email',
        '#title' => $this->t('Email address'),
        '#placeholder' => $this->t('Email address'),
        '#attributes' => ['class' => ['mail-first-step']],
        '#required' => TRUE,
      ];
      $form['subscribe'] = [
        '#type' => 'checkbox',
        '#title' => $this->t('Subscribe to newsletter'),
      ];
      $form['agree'] = [
        '#markup' => '<p class="agree">' . $this->t('By signing up you agree to the <a href="@terms">Terms and Conditions</a> and <a href="@policy">Privacy Policy</a>', ['@terms' => '/terms-and-conditions', '@policy' => '/privacy-policy']) . '</p>',
      ];
    }

    if ($this->step == 3) {
      $form['message-step'] = [
        '#markup' => '<p class="complete">' . $this->t('- Complete -') . '</p>',
      ];
      $form['message-title'] = [
        '#markup' => '<h2>' . $this->t('Thank you') . '</h2>',
      ];
    }

    if ($this->step == 1) {
      $form['buttons']['forward'] = [
        '#type' => 'submit',
        '#value' => $this->t('Next'),
        '#prefix' => '<div class="step1-button">',
        '#suffix' => '</div>',
        '#ajax' => [
          'wrapper' => 'ajax_form_multistep_form',
          'callback' => '::ajax_form_multistep_form_ajax_callback',
          'event' => 'click',
        ],
      ];
    }
    if ($this->step == 2) {
      $form['buttons']['forward'] = [
        '#type' => 'submit',
        '#value' => $this->t('Submit'),
        '#ajax' => [
          'wrapper' => 'ajax_form_multistep_form',
          'callback' => '::ajax_form_multistep_form_ajax_callback',
          'event' => 'click',
        ],
      ];
    }

    $form['#attached']['library'][] = 'drupalbook/multistep_form';
    return $form;
  }

  public function validateForm(array &$form, FormStateInterface $form_state) {
    return parent::validateForm($form, $form_state);
  }

  public function submitForm(array &$form, FormStateInterface $form_state) {
    if ($this->step == 2) {
      $values = $form_state->getValues();
      $email = $values['email'];
      // Hier können Daten gespeichert oder E-Mails versendet werden.
    }
    $this->step++;
    $form_state->setRebuild();
  }

  public function ajax_form_multistep_form_ajax_callback(array &$form, FormStateInterface $form_state) {
    return $form;
  }

}

Als nächstes erstellen wir eine Route für das Formular:

/modules/custom/drupalbook/drupalbook.routing.yml

drupalbook.multistep_form:
  path: '/multistep-form'
  defaults:
    _form: '\Drupal\drupalbook\Form\MultiStepForm'
    _title: 'Subscribe to newsletter'
  requirements:
    _permission: 'access content'

Das Formular wird dann unter /multistep-form erreichbar sein:

Formular-URL

Damit sich das Formular in einem modalen Popup öffnet, fügen Sie einen Block oder einfachen Text mit einem Link mit der CSS-Klasse use-ajax und dem Attribut data-dialog-type="modal" hinzu, der auf die Formularseite verweist. Außerdem müssen Sie die Bibliotheken core/drupal.dialog.ajax und core/jquery.form aktivieren.

Wenn Sie das über einen Block machen, könnte der Code für den Button zum Öffnen des Popup-Formulars so aussehen:

/modules/custom/drupalbook/src/Plugin/Block/SubscribeFormButton.php

<?php

namespace Drupal\drupalbook\Plugin\Block;

use Drupal\Core\Block\BlockBase;

/**
 * Provides a button subscribe to newsletter.
 *
 * @Block(
 *   id = "drupalbook_subsribe_form_button",
 *   admin_label = @Translation("Subscribe to Newsletter"),
 * )
 */
class SubscribeFormButton extends BlockBase {
  public function build() {
    $text = '<a href="/multistep-form" class="use-ajax" data-dialog-type="modal">Subscribe</a>';

    return [
      '#markup' => $text,
      '#attached' => [
        'library' => [
          'core/drupal.dialog.ajax',
          'core/jquery.form',
        ],
      ],
    ];
  }
}

Das Popup-Formular sieht dann so aus:

Newsletter Popup

Zusätzlich wird eine eigene Bibliothek aus drupalbook.libraries.yml eingebunden:

/modules/custom/drupalbook/drupalbook.libraries.yml

multistep_form:
  css:
    css/multistep_form.css: {}
  js:
    scripts/multistep_form.js: {}
  dependencies:
    - core/jquery
    - core/jquery.once

Um das Formular ansprechend zu gestalten und nötige jQuery-Plugins zu integrieren, müssen Sie weitere Dateien erstellen:

/modules/custom/drupalbook/css/multistep_form.css
/modules/custom/drupalbook/scripts/multistep_form.js

Code-Beispiele dazu finden Sie auf GitHub:
https://github.com/levmyshkin/drupalbook8