it-swarm.com.de

Validierungsfehler können nicht von einem AJAX Formular) zurückerhalten werden

Ich habe ein Drupal Formular, das über AJAX gesendet werden soll. Ich möchte überprüfen, ob die Eingabe korrekt ist. Einige Dinge passieren:

  • Die Methode validateForm wird getroffen
  • Ich kann die Fehler im Formular mit getErrors nicht sehen
  • Ich möchte die Eingabe überprüfen, und wenn ein Fehler auftritt, flashen Sie eine Nachricht in der Form, dass sie ungültig ist
  • Bei Erfolg möchte ich das Formular durch eine Erfolgsmeldung ersetzen (aber es kommt nicht so weit).

Hier ist mein Formularcode:

<?php

namespace Drupal\harlib_newsletter_signup\Form;

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

/**
 * Class NewsletterSignup.
 */
class NewsletterSignup extends FormBase {

  public $uniqueIdentifier = 'no_tagline';

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'newsletter_signup_' . $this->uniqueIdentifier;
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {

    if ($this->uniqueIdentifier == "with_tagline") {
      $show_tagline = TRUE;
    }
    else {
      $show_tagline = FALSE;
    }

    $wrapper = 'ajax-wrapper-' . $this->uniqueIdentifier;

    $form['#prefix'] = '<section class="hl__single-input-form"><div id="' . $wrapper . '">';
    $form['#suffix'] = '</div></section>';

    $form['#attributes']['class'][] = 'hl__single-input-form__form';
    $form['#attributes']['novalidate'] = 'novalidate';

    $form['title'] = [
      '#type' => 'label',
      '#for' => 'edit-email-address',
      '#title' => 'Stay in the know',
      '#attributes' => [
        'class' => [
          'hl__label',
          'hl__label--inline',
        ],
      ],
    ];

    if ($show_tagline) {
      $form['tagline'] = [
        '#markup' => '<div class="hl__single-input-form__helper-text">Sign up for email updates from MySite</div>',
      ];
    }

    $errors = $form_state->getErrors();

    if ($errors = $form_state->getErrors()) {
      $form['errors'] = [
        '#markup' => $errors['email_address'],
      ];
    }

    $form['email_address'] = [
      '#type' => 'email',
      '#size' => NULL,
      '#required' => TRUE,
      '#attributes' => [
        'placeholder' => $this->t('Email'),
        'class' => [
          'hl__input',
          'hl__input--inline',
          'js-is-required',
        ],
        'data-twig-suggestion' => 'newsletter_signup_email',
      ],
      '#prefix' => '<div class="hl__single-input-form__input-group">',
    ];

    $form['submit'] = [
      '#type' => 'button',
      '#value' => $this->t('Sign up'),
      '#submit' => ['::submitForm'],
      '#attributes' => [
        'class' => [
          'hl__button',
          'hl__button--small',
          'hl__button--inline',
        ],
        'data-twig-suggestion' => 'newsletter_signup_submit',
      ],
      '#suffix' => '</div>',
      '#ajax' => [
        'wrapper' => $wrapper,
        'method' => 'replace',
        'callback' => '::ajaxRebuildForm',
        'progress' => [
          '#type' => 'none',
        ],
      ],
    ];

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state) {
    $email_value = $form_state->getValue('email_address');

    if (empty($email_value) || !\Drupal::service('email.validator')->isValid($email_value)) {
      $form_state->setError($form['email_address'], $this->t('Please enter a valid email address.'));
    }

    if (mailchimp_is_subscribed('XXXXXXX', $email_value, TRUE)) {
      $form_state->setError($form['email_address'], $this->t('You are already subscribed to our newsletter.'));
    }
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $result = mailchimp_subscribe('XXXXXXX', $form_state->getValue('email_address'));

    if (empty($result)) {
      $form_state->setError($form['email_address'], $this->t('You are already subscribed to our newsletter.'));
    }
    else {
      drupal_set_message($this->t('Thank you for subscribing to our newsletter!'));
    }
  }

  public function ajaxRebuildForm(array $form, FormStateInterface $formState) {
    return $form;
  }

}

Ist ajaxRebuildForm notwendig? Wie kann ich das validieren? Ist setError in einem Ajax-Submit noch funktionsfähig?

BEARBEITEN: Ich habe die validateForm-Methode aktualisiert, um AjaxResponse zu verwenden. Auf meinem Bildschirm passiert nichts.

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state) {
    $response = new AjaxResponse();
    $email_value = $form_state->getValue('email_address');

    if (empty($email_value) || !\Drupal::service('email.validator')->isValid($email_value)) {
      //$form_state->setError($form['email_address'], $this->t('Please enter a valid email address.'));
      //$form_state->setRebuild();
      $response->addCommand(new CssCommand('.hl__single-input-form__input-group', ['border' => '3px solid red']));
      $response->addCommand(new AlertCommand('Heyoooo'));
      return $response;
    }

    if (mailchimp_is_subscribed('XXXXXXX', $email_value, TRUE)) {
      $form_state->setError($form['email_address'], $this->t('You are already subscribed to our newsletter.'));
    }
  }
3
Kevin

Dies stellte sich tatsächlich als eine Kombination einiger Dinge heraus:

  1. Ich habe dieses Formular mehr als einmal auf derselben Seite verwendet
  2. Es ist ein AJAX Formular), daher musste die Übermittlung eindeutig sein.

Hinzufügen:

$form['submit_' . $this->uniqueIdentifier] Anstatt von $form['submit'] hat das Problem behoben. Ich erhalte jetzt AJAX Fehler bei beiden und beide senden korrekt.

2
Kevin

Es ist wahrscheinlich mailchimp_is_subscribed das bricht es. Ich habe den Code selbst mit einer kleinen Änderung ausprobiert:

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state) {
    $email_value = $form_state->getValue('email_address');

    if (empty($email_value) || !\Drupal::service('email.validator')->isValid($email_value)) {
      $form_state->setError($form['email_address'], $this->t('Please enter a valid email address.'));
    }

    else {
      if (mailchimp_is_subscribed('XXXXXXX', $email_value, TRUE)) {
        $form_state->setError($form['email_address'], $this->t('You are already subscribed to our newsletter.'));
      }
    }
  }

(screen-shot

Wenn dies das Verhalten auf Ihrem System nicht ändert, ändern Sie das Standarddesign und testen Sie es.

Ihr Thema druckt möglicherweise die Fehler nicht. Wenn dies der Fall ist, fehlt möglicherweise der markierte Bereich für Nachrichten in Ihrer Vorlage. Suchen nach {{ page.highlighted }} in Ihrem Thema oder dem übergeordneten Thema und stellen Sie sicher, dass es gedruckt ist.

0
awm