I have a small email signup form made from extending FormBase that takes an email address and submits it to a mail service. I need to change the submit to AJAX so I can flash a success or error message.
I want to show this form more than once on a page. Once in a CTA near the top of the page, and there is a slightly different styled version in the footer.
When I added #ajax
to the submit button, only one instance of the form seems to be affected. Here is the whole form:
$info = $form_state->getBuildInfo();
$form['#prefix'] = '<section class="hl__single-input-form">';
$form['#suffix'] = '</section>';
$form['#attributes']['class'][] = 'hl__single-input-form__form';
$form['title'] = [
'#type' => 'label',
'#for' => 'edit-email-address',
'#title' => 'Stay in the know',
'#attributes' => [
'class' => [
'hl__label',
'hl__label--inline',
],
],
];
if (!empty($info['args'][0]) && $info['args'][0] == "show_tagline") {
$form['tagline'] = [
'#markup' => '<div class="hl__single-input-form__helper-text">Sign up for email updates from MySite</div>',
];
}
$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' => 'submit',
'#value' => $this->t('Sign up'),
'#attributes' => [
'class' => [
'hl__button',
'hl__button--small',
'hl__button--inline',
],
'data-twig-suggestion' => 'newsletter_signup_submit',
],
'#suffix' => '</div>',
'#ajax' => [
'wrapper' => 'hl__single-input-form',
]
];
The block in the footer that pulls the form just has this build method:
/**
* {@inheritdoc}
*/
public function build() {
return ['form' => $this->formBuilder->getForm('\Drupal\harlib_newsletter_signup\Form\NewsletterSignup')];
}
The preprocess for the Paragraph that outputs the form when being themed:
$variables['signup_form'] = \Drupal::service('form_builder')->getForm('\Drupal\harlib_newsletter_signup\Form\NewsletterSignup', "show_tagline");
How can I support having this form on the page more than once, both with the same AJAX action on submit? Also, how can I avoid overwriting the wrong wrapper with an AjaxCommand?
edit: validateForm method:
/**
* {@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.'));
}
}