improvements-2.x-dev/modules/improvements_contact/improvements_contact.ajax.inc
modules/improvements_contact/improvements_contact.ajax.inc
<?php
use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\Xss;
use Drupal\contact\ContactFormInterface as ContactFormEntityInterface;
use Drupal\contact\Entity\Message as ContactMessageEntity;
use Drupal\contact\MessageForm as ContactMessageForm;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\HtmlCommand;
use Drupal\Core\Ajax\OpenModalDialogCommand;
use Drupal\Core\Ajax\PrependCommand;
use Drupal\Core\Ajax\ReplaceCommand;
use Drupal\Core\Entity\EntityFormInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Render\Markup;
use Drupal\improvements_form\Ajax\AddClassCommand;
use Drupal\improvements_form\Ajax\FormResetCommand;
use Symfony\Component\HttpFoundation\Response;
/**
* Implements hook_form_BASE_FORM_ID_alter(): contact_form_form.
*
* @see improvements_contact_form_contact_form_form_alter()
*/
function improvements_contact_ajax_form_contact_form_form_alter(array &$form, FormStateInterface $form_state): void {
$contact_form_form_object = $form_state->getFormObject(); /** @var EntityFormInterface $contact_form_form_object */
$contact_form_entity = $contact_form_form_object->getEntity(); /** @var ContactFormEntityInterface $contact_form_entity */
$form['additional_settings']['ajax_submit'] = [
'#type' => 'checkbox',
'#title' => t('AJAX submit'),
'#default_value' => $contact_form_entity->getThirdPartySetting('improvements', 'ajax_submit'),
'#weight' => 13,
];
$form['additional_settings']['ajax_submit_method'] = [
'#type' => 'radios',
'#title' => t('Show successful message'),
'#options' => [
'form_item' => t('In form'),
'form' => t('Instead of a form'),
'dialog' => t('In dialog'),
],
'#default_value' => $contact_form_entity->getThirdPartySetting('improvements', 'ajax_submit_method', 'form'),
'#states' => [
'visible' => [
':input[name="ajax_submit"]' => [
'checked' => TRUE,
],
],
],
'#weight' => 14,
];
$form['additional_settings']['dialog_title'] = [
'#type' => 'textfield',
'#title' => t('Dialog title'),
'#default_value' => $contact_form_entity->getThirdPartySetting('improvements', 'dialog_title'),
'#states' => $form['additional_settings']['ajax_submit_method']['#states'],
'#weight' => 15,
];
$form['additional_settings']['ajax_success_message'] = [
'#type' => 'textarea',
'#title' => t('AJAX success message'),
'#default_value' => $contact_form_entity->getThirdPartySetting('improvements', 'ajax_success_message'),
'#states' => $form['additional_settings']['ajax_submit_method']['#states'],
'#weight' => 16,
];
$form['#entity_builders'][] = 'improvements_contact_ajax_form_entity_builder';
}
/**
* Contact form entity builder.
*
* @see improvements_contact_form_contact_form_form_alter().
*/
function improvements_contact_ajax_form_entity_builder(string $entity_type, ContactFormEntityInterface $contact_form, array &$form, FormStateInterface $form_state): void {
// Save additional settings
$simple_settings = [
'ajax_submit',
'ajax_submit_method',
'dialog_title',
'ajax_success_message',
];
foreach ($simple_settings as $setting_name) {
$contact_form->setThirdPartySetting('improvements', $setting_name, $form_state->getValue($setting_name));
}
}
/**
* Implements hook_form_BASE_FORM_ID_alter(): contact_message_form.
*
* @see improvements_contact_form_contact_message_form_alter()
*/
function improvements_contact_ajax_form_contact_message_form_alter(array &$form, FormStateInterface $form_state, string $form_id): void {
$contact_message_form_object = $form_state->getFormObject(); /** @var ContactMessageForm $contact_message_form_object */
$contact_message_entity = $contact_message_form_object->getEntity(); /** @var ContactMessageEntity $contact_message_entity */
$contact_form_entity = $contact_message_entity->getContactForm();
if ($contact_form_entity->getThirdPartySetting('improvements', 'ajax_submit')) {
//$form_html_id = Html::getId($contact_message_form_object->getFormId());
//$form['#id'] = $form_html_id;
$form['actions']['submit']['#ajax'] = [
'callback' => 'improvements_contact_ajax_form_contact_message_form_ajax',
'event' => 'click',
'disable-refocus' => TRUE,
];
if ($contact_form_entity->getThirdPartySetting('improvements', 'ajax_submit_method') == 'dialog') {
$form['#attached']['library'][] = 'core/drupal.dialog.ajax';
}
}
}
/**
* Contact form ajax submit callback.
*
* @see improvements_contact_form_contact_message_form_alter()
*/
function improvements_contact_ajax_form_contact_message_form_ajax(array &$form, FormStateInterface $form_state): Response {
$response = new AjaxResponse();
//$form_selector = '#' . $form['#id'];
$form_selector = 'form:has(input[name="form_build_id"][value="' . $form['#build_id'] . '"])';
$contact_form_object = $form_state->getFormObject(); /** @var ContactMessageForm $contact_form_object */
$contact_message_entity = $contact_form_object->getEntity(); /** @var ContactMessageEntity $contact_message_entity */
$contact_form_entity = $contact_message_entity->getContactForm();
if ($form_state->hasAnyErrors()) {
$form['status_messages'] = [
'#type' => 'status_messages',
'#weight' => -1000,
];
$response->addCommand(new ReplaceCommand($form_selector, $form));
}
else {
// Delete status messages (warnings and errors are keep)
\Drupal::messenger()->deleteByType(MessengerInterface::TYPE_STATUS);
// Show success message
$success_message = $contact_form_entity->getThirdPartySetting('improvements', 'ajax_success_message') ?: $contact_form_entity->getMessage();
$success_message = \Drupal::token()->replace($success_message, ['contact_message' => $contact_message_entity]);
$success_message_build = [
'status_message' => [
'#type' => 'status_messages'
],
'success_message' => [
'#theme' => 'contact_success_message',
'#message' => Markup::create($success_message) ?: t('Form is submitted'),
],
];
$ajax_submit_method = $contact_form_entity->getThirdPartySetting('improvements', 'ajax_submit_method', 'form');
// Show message in form
if ($ajax_submit_method == 'form_item') {
$response->addCommand(new AddClassCommand($form_selector, 'form-contains-success-message'));
$response->addCommand(new PrependCommand($form_selector, $success_message_build));
}
// Show message instead of a form
elseif ($ajax_submit_method == 'form') {
$response->addCommand(new HtmlCommand($form_selector, $success_message_build));
}
// Show message in dalog
elseif ($ajax_submit_method == 'dialog') {
$dialog_title = $contact_form_entity->getThirdPartySetting('improvements', 'dialog_title');
$open_dialog_command = new OpenModalDialogCommand($dialog_title, $success_message_build);
$open_dialog_command->setDialogTitle(Xss::filter($dialog_title, array_merge(Xss::getHtmlTagList(), ['b']))); // Allow html in title
$response->addCommand($open_dialog_command);
$response->addCommand(new FormResetCommand($form_selector));
}
}
\Drupal::moduleHandler()->alter([
'contact_message_form_ajax_response',
'contact_message_form_' . $contact_form_entity->id() . '_ajax_response',
], $response, $form, $form_state);
return $response;
}
