0

I Have a form on a page which updates a single field of a Node. The form uses ajax to update the field and returns the newly saved entity and replaces the current HTML so the new field is showing up correctly.

This works fine the first time the form is fired, but breaks after that with the following error in my console:

An AJAX HTTP error occurred

There's no further error report which would tell me more about this error.

Here is my form code:

<?php

namespace Drupal\ats_tweaks\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\node\Entity\Node;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\ReplaceCommand;

use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Onboarding form.
 */
class UpdateApplicationStatusForm extends FormBase {

  /**
   * Form ID.
   *
   * @var string
   */
  protected static $formId;

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    $formId = 'update_application_status_form';
    if (self::$formId) {
      $formId = $formId . '_' . self::$formId;
    }
    return $formId;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    // Instantiates this form class.
    $instance = parent::create($container);
    return $instance;
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $node_id = $form_state->getBuildInfo()['args'][0];

    self::$formId = $node_id;
    $application = Node::load($node_id);

    $field_definitions = \Drupal::service('entity_field.manager')->getFieldDefinitions('node', 'application');
    if (isset($field_definitions['field_application_status'])) {
      $status_options = options_allowed_values($field_definitions['field_application_status']->getFieldStorageDefinition());
    }

    $form['#attributes']['id'] = $this->getFormId();

    // Application select list.
    $form['status'] = [
      '#type' => 'select',
      '#title' => $this->t('Sollicitatiestatus'),
      '#options' => $status_options,
      '#default_value' => $application->get('field_application_status')->getValue()[0]['value'],
      '#ajax' => [
        'callback' => [$this, 'submitForm'],
        'wrapper' => 'mapping',
        'effect' => 'fade',
      ],
    ];

    $form['nid'] = [
      '#type' => 'hidden',
      '#default_value' => $node_id,
      '#value' => $node_id,
    ];

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $node_id = $form_state->getValues()['nid'];

    $application = Node::load($node_id);

    $application->set('field_application_status', $form_state->getValues()['status']);
    $application->save();

    $view_builder = \Drupal::entityTypeManager()->getViewBuilder('node');
    $storage = \Drupal::entityTypeManager()->getStorage('node');
    $node = $storage->load($node_id);

    $build = $view_builder->view($node, 'teaser');
    $form_state->setRebuild(TRUE);

    $response = new AjaxResponse();
    $response->addCommand(new ReplaceCommand('#application-' . $node_id, $build));
    return $response;
  }

}

4
  • This is not a good idea naming the ajax callback FormInterface::submitForm. These are two different methods. When you specify a wrapper the ajax callback only needs to return the new content of the wrapper. Put the rest of the code in the appropriate Form API methods.
    – 4k4
    Sep 7 '21 at 13:03
  • As 4x4 mentioned, you have set up your submit response and ajax response as the same function - this is your issue.
    – Jaypan
    Sep 7 '21 at 14:22
  • Thanks for the input, (I'm the OP. created the post without signing in...). I have changed the function name to something different and removed the wrapper as this is not needed for my response. This does not however fix my error. Hope you have some other ideas
    – Kimimaruu
    Sep 8 '21 at 7:43
  • You need to set the rebuild in the submit handler, not the ajax callback.
    – Jaypan
    Sep 9 '21 at 15:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.