J'ai un formulaire Drupal qui doit être soumis via AJAX. Je veux valider la saisie est correcte. Quelques choses se produisent:
validateForm
est atteintegetErrors
Voici mon code de formulaire:
<?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;
}
}
ajaxRebuildForm
est-il nécessaire? Comment puis-je valider cela? setError
est-il toujours utilisable dans une soumission ajax?
EDIT: J'ai mis à jour la méthode validateForm pour utiliser AjaxResponse. Rien ne se passe sur mon écran.
/**
* {@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.'));
}
}
Cela s'est avéré être une combinaison de quelques éléments:
Ajouter:
$form['submit_' . $this->uniqueIdentifier]
au lieu de $form['submit']
a résolu le problème. Je reçois maintenant des erreurs AJAX sur les deux, et les deux soumettent correctement.
C'est probablement mailchimp_is_subscribed
qui le brise. J'ai essayé le code moi-même avec un léger changement:
/**
* {@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.'));
}
}
}
Si cela ne change pas le comportement sur votre système, changez le thème par défaut et testez-le.
Votre thème n'imprime peut-être pas les erreurs. Si c'est le cas, il se peut que la région en surbrillance des messages soit manquante dans votre modèle. Rechercher {{ page.highlighted }}
dans votre thème ou son parent et assurez-vous qu'il est imprimé.