diff --git a/modules/mailchimp_signup/config/schema/mailchimp_signup.schema.yml b/modules/mailchimp_signup/config/schema/mailchimp_signup.schema.yml index 562ce01..967e516 100644 --- a/modules/mailchimp_signup/config/schema/mailchimp_signup.schema.yml +++ b/modules/mailchimp_signup/config/schema/mailchimp_signup.schema.yml @@ -62,6 +62,9 @@ mailchimp_signup.mailchimp_signup.*: destination: type: string label: 'Destination' + ajax: + type: boolean + label: 'Ajax form submit' mergefields: type: sequence label: 'Mergefields' diff --git a/modules/mailchimp_signup/src/Form/MailchimpSignupForm.php b/modules/mailchimp_signup/src/Form/MailchimpSignupForm.php index 59cff01..5937431 100644 --- a/modules/mailchimp_signup/src/Form/MailchimpSignupForm.php +++ b/modules/mailchimp_signup/src/Form/MailchimpSignupForm.php @@ -153,6 +153,13 @@ class MailchimpSignupForm extends EntityForm { '#default_value' => isset($signup->settings['destination']) ? $signup->settings['destination'] : NULL, ); + $form['settings']['ajax_submit'] = array( + '#type' => 'checkbox', + '#title' => t('AJAX Form Submit Mode'), + '#description' => t('Select if signup form submit should use AJAX instead of default page reload. Destination page will be ignored if checked.'), + '#default_value' => isset($signup->settings['ajax_submit']) ? $signup->settings['ajax_submit'] : FALSE, + ); + $form['mc_lists_config'] = array( '#type' => 'details', '#title' => $this->t('Mailchimp Audience Selection & Configuration'), diff --git a/modules/mailchimp_signup/src/Form/MailchimpSignupPageForm.php b/modules/mailchimp_signup/src/Form/MailchimpSignupPageForm.php index 8c31251..96c612b 100644 --- a/modules/mailchimp_signup/src/Form/MailchimpSignupPageForm.php +++ b/modules/mailchimp_signup/src/Form/MailchimpSignupPageForm.php @@ -2,6 +2,10 @@ namespace Drupal\mailchimp_signup\Form; +use Drupal\Component\Utility\Html; +use Drupal\Core\Ajax\AjaxResponse; +use Drupal\Core\Ajax\ChangedCommand; +use Drupal\Core\Ajax\HtmlCommand; use Drupal\Core\Form\FormBase; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Url; @@ -80,6 +84,16 @@ class MailchimpSignupPageForm extends FormBase { '#markup' => $this->signup->description, ); + // If the form is configured to submit via AJAX, add an empty container + // element. This element is going to be replaced with the returned AJAX + // response. + if (isset($this->signup->settings['ajax_submit']) && $this->signup->settings['ajax_submit']) { + $form['response'] = [ + '#prefix' => '
', + '#suffix' => '
', + ]; + } + $form['mailchimp_lists'] = array('#tree' => TRUE); $lists = mailchimp_get_lists($this->signup->mc_lists); @@ -212,6 +226,19 @@ class MailchimpSignupPageForm extends FormBase { '#disabled' => (empty($lists)), ]; + // Add a wrapper element to the form if it is configured for AJAX submits. + if ($this->signup->settings['ajax_submit']) { + $form_wrapper = Html::getId($this->formId); + $response_wrapper = "mailchimp-response-{$this->formId}-wrapper"; + $form['actions']['submit']['#id'] = $form_wrapper . '-edit-submit'; + $form['#prefix'] = '
'; + $form['#suffix'] = '
'; + $form['actions']['submit']['#ajax'] = [ + 'callback' => '::ajaxSubmit', + 'response_wrapper' => $response_wrapper, + ]; + } + return $form; } @@ -324,4 +351,31 @@ class MailchimpSignupPageForm extends FormBase { $form_state->setRedirectUrl($destination_url); } + /** + * Ajax submit handler. + * + * @param array $form + * The form itself. + * @param \Drupal\Core\Form\FormStateInterface $form_state + * The current form state. + * + * @return \Drupal\Core\Ajax\AjaxResponse + * A ajax response. + */ + public function ajaxSubmit(array $form, FormStateInterface $form_state) { + $response = new AjaxResponse(); + $response_wrapper_id = '#' . $form['actions']['submit']['#ajax']['response_wrapper']; + + // Simply return any status messages as a content the the response wrapper. + $status_messages = ['#type' => 'status_messages']; + $content = \Drupal::service('renderer')->renderRoot($status_messages); + $response->addCommand(new HtmlCommand($response_wrapper_id, $content)); + + // Also add an extra class to the form itself to signify the form changed. + $form_wrapper_id = '#' . Html::getId($this->formId); + $response->addCommand(new ChangedCommand($form_wrapper_id)); + + return $response; + } + }