2

I'm trying to create a node in a dialog with the following link:

Enter the title of a registration form or <a class="use-ajax" 
    data-dialog-options="{&quot;width&quot;:800}" 
    data-dialog-type="modal" 
    href="/node/add/mycontenttype?enableAjaxSubmit=true">
    create a new registration form.
</a>

The callback _mymodule_close_dialog() runs perfectly when there are no validation errors. But when there is an error (e.g. the title is empty), JS just outputs an error Uncaught TypeError: this.url is undefined.

I can get rid of the JS error by preventing the form actions from becoming model buttons, but then the form just silently fails.

How can I show a form's error messages when creating a node in a dialog?

The callback:

/**
 * Implements hook_form_BASE_FORM_ID_alter() for \Drupal\node\NodeForm.
 */
function mymodule_form_node_mycontenttype_form_alter(&$form, FormStateInterface $form_state) {
    $enableAjaxSubmit = \Drupal::request()->query->get('enableAjaxSubmit');
    if (!empty($enableAjaxSubmit) && $enableAjaxSubmit === 'true') {    
      $form['#attached']['library'][] = 'core/drupal.dialog.ajax';
      $form['#attached']['library'][] = 'core/jquery.form';

      $form['actions']['submit']['#attributes']['class'][] = 'use-ajax-submit';
      $form['actions']['submit']['#submit'][] = '_mymodule_close_dialog';
    }
}

use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\CloseModalDialogCommand;
use Drupal\Core\Ajax\PrependCommand;
use Drupal\Core\Ajax\AlertCommand;

function _mymodule_close_dialog(array &$form, FormStateInterface $form_state) {
  $response = new AjaxResponse();

  // if (!$form_state->getErrors()) {
    $response->addCommand(new CloseModalDialogCommand());
  // }

  $messages = ['#type' => 'status_messages'];
  $response->addCommand(new PrependCommand('.some-wrapper', $messages));

  $form_state->setResponse($response);
}

I followed:

Update

Changed:

$form['actions']['submit']['#submit'][] = '_mymodule_close_dialog';

To:

$form['actions']['submit']['#ajax']['callback'] = '_mymodule_close_dialog'; // Rename function to remove `_`
$form['actions']['submit']['#ajax']['url'] = \Drupal\Core\Url::fromRoute('node.add', ['node_type' => $contentType]);
$form['actions']['submit']['#ajax']['options'] = [
  'query' => [
    \Drupal\Core\Form\FormBuilderInterface::AJAX_FORM_REQUEST => TRUE,
  ],
];

But getting a PHP error:

Symfony\Component\HttpKernel\Exception\HttpException: The specified #ajax callback is empty or not callable. in Drupal\Core\Form\FormAjaxResponseBuilder->buildResponse()

When I debug($triggering_element) in the FormAjaxResponseBuilder file, the submit element did not have an #ajax key or the use-ajax-submit class. Thus, the triggering element is not ultimately altered.

Any ideas?

1 Answer 1

0

and a bit of: https://www.drupal.org/project/drupal/issues/2934463#comment-13180158

You missed adding this part to your alter, which should fix your url undefined problem.

$form['actions']['submit']['#ajax']['url'] = \Drupal\Core\Url::fromRoute('node.add');
$form['actions']['submit']['#ajax']['options'] = [
  'query' => [
    Drupal\Core\Form\FormBuilderInterface::AJAX_FORM_REQUEST => TRUE,
  ],
];
2
  • I tried adding the code below $form['actions']['submit']['#submit'][] = '_mymodule_close_dialog'; but then it stopped saving. Isn't the above code for opening the node.add form (and not for when saving the node form)? Or am I not understanding something? Aug 25, 2021 at 21:22
  • I added an update with your solution. Unfortunately, Drupal is not using the altered element with the #ajax key. Aug 27, 2021 at 1:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.