You are here

public function FormAjaxResponseBuilder::buildResponse in Drupal 8

Same name and namespace in other branches
  1. 9 core/lib/Drupal/Core/Form/FormAjaxResponseBuilder.php \Drupal\Core\Form\FormAjaxResponseBuilder::buildResponse()
  2. 10 core/lib/Drupal/Core/Form/FormAjaxResponseBuilder.php \Drupal\Core\Form\FormAjaxResponseBuilder::buildResponse()

Builds a response for an AJAX form.

Parameters

\Symfony\Component\HttpFoundation\Request $request: The current request.

array $form: An associative array containing the structure of the form.

\Drupal\Core\Form\FormStateInterface $form_state: The current state of the form.

array $commands: An array of AJAX commands to apply to the form.

Return value

\Drupal\Core\Ajax\AjaxResponse An AJAX response representing the form and its AJAX commands.

Throws

\Symfony\Component\HttpKernel\Exception\HttpException Thrown if the AJAX callback is not a callable.

Overrides FormAjaxResponseBuilderInterface::buildResponse

File

core/lib/Drupal/Core/Form/FormAjaxResponseBuilder.php, line 50

Class

FormAjaxResponseBuilder
Builds an AJAX form response.

Namespace

Drupal\Core\Form

Code

public function buildResponse(Request $request, array $form, FormStateInterface $form_state, array $commands) {

  // If the form build ID has changed, issue an Ajax command to update it.
  if (isset($form['#build_id_old']) && $form['#build_id_old'] !== $form['#build_id']) {
    $commands[] = new UpdateBuildIdCommand($form['#build_id_old'], $form['#build_id']);
  }

  // We need to return the part of the form (or some other content) that needs
  // to be re-rendered so the browser can update the page with changed
  // content. It is up to the #ajax['callback'] function of the element (may
  // or may not be a button) that triggered the Ajax request to determine what
  // needs to be rendered.
  $callback = NULL;
  if (($triggering_element = $form_state
    ->getTriggeringElement()) && isset($triggering_element['#ajax']['callback'])) {
    $callback = $triggering_element['#ajax']['callback'];
  }
  $callback = $form_state
    ->prepareCallback($callback);
  if (empty($callback) || !is_callable($callback)) {
    throw new HttpException(500, 'The specified #ajax callback is empty or not callable.');
  }
  $result = call_user_func_array($callback, [
    &$form,
    &$form_state,
    $request,
  ]);

  // If the callback is an #ajax callback, the result is a render array, and
  // we need to turn it into an AJAX response, so that we can add any commands
  // we got earlier; typically the UpdateBuildIdCommand when handling an AJAX
  // submit from a cached page.
  if ($result instanceof AjaxResponse) {
    $response = $result;
  }
  else {

    // At this point we know callback returned a render element. If the
    // element is part of the group (#group is set on it) it won't be rendered
    // unless we remove #group from it. This is caused by
    // \Drupal\Core\Render\Element\RenderElement::preRenderGroup(), which
    // prevents all members of groups from being rendered directly.
    if (!empty($result['#group'])) {
      unset($result['#group']);
    }

    /** @var \Drupal\Core\Ajax\AjaxResponse $response */
    $response = $this->ajaxRenderer
      ->renderResponse($result, $request, $this->routeMatch);
  }
  foreach ($commands as $command) {
    $response
      ->addCommand($command, TRUE);
  }
  return $response;
}