1. 8.5.x core/core.api.php ajax
  2. 8.0.x core/core.api.php ajax
  3. 8.1.x core/core.api.php ajax
  4. 8.2.x core/core.api.php ajax
  5. 8.3.x core/core.api.php ajax
  6. 8.4.x core/core.api.php ajax
  7. 8.6.x core/core.api.php ajax
  8. 7.x includes/ajax.inc ajax

Overview for Drupal's Ajax API.

Overview of Ajax

Ajax is the process of dynamically updating parts of a page's HTML based on data from the server. When a specified event takes place, a PHP callback is triggered, which performs server-side logic and may return updated markup or JavaScript commands to run. After the return, the browser runs the JavaScript or updates the markup on the fly, with no full page refresh necessary.

Many different events can trigger Ajax responses, including:

  • Clicking a button
  • Pressing a key
  • Moving the mouse

Ajax responses in forms

Forms that use the Drupal Form API (see the Form API topic for more information about forms) can trigger AJAX responses. Here is an outline of the steps:

  • Add property '#ajax' to a form element in your form array, to trigger an Ajax response.
  • Write an Ajax callback to process the input and respond.

See sections below for details on these two steps.

Adding Ajax triggers to a form

As an example of adding Ajax triggers to a form, consider editing a date format, where the user is provided with a sample of the generated date output as they type. To accomplish this, typing in the text field should trigger an Ajax response. This is done in the text field form array element in \Drupal\config_translation\FormElement\DateFormat::getFormElement():

'#ajax' => array(
  'callback' => 'Drupal\config_translation\FormElement\DateFormat::ajaxSample',
  'event' => 'keyup',
  'progress' => array(
    'type' => 'throbber',
    'message' => NULL,

As you can see from this example, the #ajax property for a form element is an array. Here are the details of its elements, all of which are optional:

  • callback: The callback to invoke to handle the server side of the Ajax event. More information on callbacks is below in Setting up a callback to process Ajax.
  • wrapper: The HTML 'id' attribute of the area where the content returned by the callback should be placed. Note that callbacks have a choice of returning content or JavaScript commands; 'wrapper' is used for content returns.
  • method: The jQuery method for placing the new content (used with 'wrapper'). Valid options are 'replaceWith' (default), 'append', 'prepend', 'before', 'after', or 'html'. See http://api.jquery.com/category/manipulation/ for more information on these methods.
  • effect: The jQuery effect to use when placing the new HTML (used with 'wrapper'). Valid options are 'none' (default), 'slide', or 'fade'.
  • speed: The effect speed to use (used with 'effect' and 'wrapper'). Valid options are 'slow' (default), 'fast', or the number of milliseconds the effect should run.
  • event: The JavaScript event to respond to. This is selected automatically for the type of form element; provide a value to override the default.
  • prevent: A JavaScript event to prevent when the event is triggered. For example, if you use event 'mousedown' on a button, you might want to prevent 'click' events from also being triggered.
  • progress: An array indicating how to show Ajax processing progress. Can contain one or more of these elements:

    • type: Type of indicator: 'throbber' (default) or 'bar'.
    • message: Translated message to display.
    • url: For a bar progress indicator, URL path for determining progress.
    • interval: For a bar progress indicator, how often to update it.
  • url: A \Drupal\Core\Url to which to submit the Ajax request. If omitted, defaults to either the same URL as the form or link destination is for someone with JavaScript disabled, or a slightly modified version (e.g., with a query parameter added, removed, or changed) of that URL if necessary to support Drupal's content negotiation. It is recommended to omit this key and use Drupal's content negotiation rather than using substantially different URLs between Ajax and non-Ajax.

Setting up a callback to process Ajax

Once you have set up your form to trigger an Ajax response (see Adding Ajax triggers to a form above), you need to write some PHP code to process the response. If you use 'path' in your Ajax set-up, your route controller will be triggered with only the information you provide in the URL. If you use 'callback', your callback method is a function, which will receive the $form and $form_state from the triggering form. You can use $form_state to get information about the data the user has entered into the form. For instance, in the above example for the date format preview, \Drupal\config_translation\FormElement\DateFormat\ajaxSample() does this to get the format string entered by the user:

$format_value = \Drupal\Component\Utility\NestedArray::getValue($form_state
  ->getValues(), $form_state

Once you have processed the input, you have your choice of returning HTML markup or a set of Ajax commands. If you choose to return HTML markup, you can return it as a string or a renderable array, and it will be placed in the defined 'wrapper' element (see documentation above in Adding Ajax triggers to a form). In addition, any messages returned by drupal_get_messages(), themed as in status-messages.html.twig, will be prepended.

To return commands, you need to set up an object of class \Drupal\Core\Ajax\AjaxResponse, and then use its addCommand() method to add individual commands to it. In the date format preview example, the format output is calculated, and then it is returned as replacement markup for a div like this:

$response = new AjaxResponse();
  ->addCommand(new ReplaceCommand('#edit-date-format-suffix', '<small id="edit-date-format-suffix">' . $format . '</small>'));
return $response;

The individual commands that you can return implement interface \Drupal\Core\Ajax\CommandInterface. Available commands provide the ability to pop up alerts, manipulate text and markup in various ways, redirect to a new URL, and the generic \Drupal\Core\Ajax\InvokeCommand, which invokes an arbitrary jQuery command.

As noted above, status messages are prepended automatically if you use the 'wrapper' method and return HTML markup. This is not the case if you return commands, but if you would like to show status messages, you can add

  '#type' => 'status_messages',

to a render array, use drupal_render() to render it, and add a command to place the messages in an appropriate location.

Other methods for triggering Ajax

Here are some additional methods you can use to trigger Ajax responses in Drupal:

  • Add class 'use-ajax' to a link. The link will be loaded using an Ajax call. When using this method, the href of the link can contain '/nojs/' as part of the path. When the Ajax JavaScript processes the page, it will convert this to '/ajax/'. The server is then able to easily tell if this request was made through an actual Ajax request or in a degraded state, and respond appropriately.
  • Add class 'use-ajax-submit' to a submit button in a form. The form will then be submitted via Ajax to the path specified in the #action. Like the ajax-submit class on links, this path will have '/nojs/' replaced with '/ajax/' so that the submit handler can tell if the form was submitted in a degraded state or not.
  • Add property '#autocomplete_route_name' to a text field in a form. The route controller for this route must return an array of options for autocomplete, as a \Symfony\Component\HttpFoundation\JsonResponse object. See the Routing topic for more information about routing.


core/core.api.php, line 2304
Documentation landing page and topics, plus core library hooks.


Namesort descending Location Description
AddCssCommand core/lib/Drupal/Core/Ajax/AddCssCommand.php An AJAX command for adding css to the page via ajax.
AfterCommand core/lib/Drupal/Core/Ajax/AfterCommand.php An AJAX command for calling the jQuery after() method.
Ajax core/lib/Drupal/Core/Render/Element/Ajax.php Provides a render element for adding Ajax to a render element.
AjaxResponse core/lib/Drupal/Core/Ajax/AjaxResponse.php JSON response object for AJAX requests.
AlertCommand core/lib/Drupal/Core/Ajax/AlertCommand.php AJAX command for a javascript alert box.
AppendCommand core/lib/Drupal/Core/Ajax/AppendCommand.php An AJAX command for calling the jQuery append() method.
BeforeCommand core/lib/Drupal/Core/Ajax/BeforeCommand.php An AJAX command for calling the jQuery before() method.
ChangedCommand core/lib/Drupal/Core/Ajax/ChangedCommand.php An AJAX command for marking HTML elements as changed.
CloseDialogCommand core/lib/Drupal/Core/Ajax/CloseDialogCommand.php Defines an AJAX command that closes the current active dialog.
CloseModalDialogCommand core/lib/Drupal/Core/Ajax/CloseModalDialogCommand.php Defines an AJAX command that closes the currently visible modal dialog.
CssCommand core/lib/Drupal/Core/Ajax/CssCommand.php An AJAX command for calling the jQuery css() method.
DataCommand core/lib/Drupal/Core/Ajax/DataCommand.php An AJAX command for implementing jQuery's data() method.
HtmlCommand core/lib/Drupal/Core/Ajax/HtmlCommand.php AJAX command for calling the jQuery html() method.
InsertCommand core/lib/Drupal/Core/Ajax/InsertCommand.php Generic AJAX command for inserting content.
InvokeCommand core/lib/Drupal/Core/Ajax/InvokeCommand.php AJAX command for invoking an arbitrary jQuery method.
OpenDialogCommand core/lib/Drupal/Core/Ajax/OpenDialogCommand.php Defines an AJAX command to open certain content in a dialog.
OpenModalDialogCommand core/lib/Drupal/Core/Ajax/OpenModalDialogCommand.php Defines an AJAX command to open certain content in a dialog in a modal dialog.
OpenOffCanvasDialogCommand core/modules/outside_in/src/Ajax/OpenOffCanvasDialogCommand.php Defines an AJAX command to open content in a dialog in a off-canvas tray.
PrependCommand core/lib/Drupal/Core/Ajax/PrependCommand.php AJAX command for calling the jQuery insert() method.
RedirectCommand core/lib/Drupal/Core/Ajax/RedirectCommand.php Defines an AJAX command to set the window.location, loading that URL.
RemoveCommand core/lib/Drupal/Core/Ajax/RemoveCommand.php AJAX command for calling the jQuery remove() method.
ReplaceCommand core/lib/Drupal/Core/Ajax/ReplaceCommand.php AJAX command for calling the jQuery replace() method.
RestripeCommand core/lib/Drupal/Core/Ajax/RestripeCommand.php AJAX command for resetting the striping on a table.
SetDialogOptionCommand core/lib/Drupal/Core/Ajax/SetDialogOptionCommand.php Defines an AJAX command that sets jQuery UI dialog properties.
SetDialogTitleCommand core/lib/Drupal/Core/Ajax/SetDialogTitleCommand.php Defines an AJAX command that sets jQuery UI dialog properties.
SettingsCommand core/lib/Drupal/Core/Ajax/SettingsCommand.php AJAX command for adjusting Drupal's JavaScript settings.
UpdateBuildIdCommand core/lib/Drupal/Core/Ajax/UpdateBuildIdCommand.php AJAX command for updating the value of a hidden form_build_id input element on a form. It requires the form passed in to have keys for both the old build ID in #build_id_old and the new build ID in #build_id.


Namesort descending Location Description
CommandInterface core/lib/Drupal/Core/Ajax/CommandInterface.php AJAX command interface.
CommandWithAttachedAssetsInterface core/lib/Drupal/Core/Ajax/CommandWithAttachedAssetsInterface.php Interface for Ajax commands that render content and attach assets.


Namesort descending Location Description
CommandWithAttachedAssetsTrait core/lib/Drupal/Core/Ajax/CommandWithAttachedAssetsTrait.php Trait for Ajax commands that render content and attach assets.


gambry’s picture

If you choose to return HTML markup, you can return it as a string or a renderable array

That's not true. Argument 1 passed to Drupal\Core\Render\MainContent\AjaxRenderer::renderResponse() must be of the type array.

So either return a renderable element or an instance of \Drupal\Core\Ajax\AjaxResponse.

karthikeyan-manivasagam’s picture

Is it possible to replace container from ajax response and replace a block from ajax response in same call with two operations. having ajax for link type

pjohn’s picture

Is there a way to add or remove classes from an element with a command?

Edit: Never mind; there is! InvokeCommand can invoke any jQuery method, including addClass.

Zerdiox’s picture

'Drupal\config_translation\FormElement\DateFormat::ajaxSample' is given as an example for a callback. Using this method you won't have access to your form object.

Instead use ::ajaxSample and you will have access to your form object in your callback function.

RajabNatshah’s picture

You could only return a JSON

$response = new JsonResponse(array("message" => "Hi", 200));
return $response;

Karol Haltenberger’s picture

The insert (insert, append, replace etc.) commands will only insert the response data as it is if the data is exactly a single html element.
Any additional text, including whitespaces and newlines (eg. at the end of a template file) or html elements and the whole thing will get wrapped in a generic div element before insertion.

taggartj’s picture

Just to have a play add some markup to your form or view or whatever and add...

<a href="/nojs/somelink" class="use-ajax btn btn-default">Test Ajax </a>

you will see that ajax is called ... now all you have to do is make a rout that handles the return ps ad as much query parameters as you want !

//in controller with rout "/somelink" ^^^ with out the "/nojs/" as drupal knows that means use ajax
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\ReplaceCommand;
public function somelinkMethod() {
    $response = new AjaxResponse();
    return $response->addCommand(new ReplaceCommand(
        'some markup')


then if you want to add more values to the post add some js to your module
that you can copy the whole beforeSerialize function from core/misc/ajax.js

 Drupal.Ajax.prototype.beforeSerialize = function (element, options) {
// right before bottom
options.data['some_custom_thing'] = 'test'; 

while there you will see Drupal.Ajax.prototype.beforeSubmit
but that did not work on links.

bribread22’s picture

Thanks, this is a helpful example of using Ajax with links. However, I tried using nojs once as the first parameter, and it didn't work for me for some reason. However, it did work when I had a custom argument in front of it.

If I may add, whoever follows this example will need to also remember to add the route as you mentioned in your example for the Ajax callback. The views_ui module provided in D8 core has a good amount of Ajax callbacks to follow along with. In your my_module.routing.yml file (create it if it doesn't exist), the callback for your example might look something like this:

  path: '/my-module/{js}'
    _controller: '\Drupal\my_module\Form\Ajax\MyAjaxForm::someLinkMethod'
    js: 'nojs|ajax'
sriharsha.uppuluri’s picture

I am using form alter to add the #ajax submit with attribute class of use-ajax-submit. But it's not working.

pnagornyak’s picture

Check form[#action] first, it should be link to your form page (you need to create route with defaults: _form property if no exists)

nehapandya55’s picture

I have added link in views block in footer to flagged all content, I only want to perform action on clicking link.

<a id='target-element' href="nojs/ignore_all" class="use-ajax btn btn-default">Ignore all</a>

In routing file i have written below code

  path: '/nojs/ignore_all'
    _controller: '\Drupal\digicare\Controller\DigicareController::ignore_all'
    _title: 'ignore_all'
    _permission: 'access content'

and in controller i have written below code

namespace Drupal\digicare\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Url;
use Drupal\Core\Link;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\ReplaceCommand;
 * Provides route responses for the Example module.
class DigicareController extends ControllerBase {
   * Returns a ajax callback.
   * @return array
   *   A simple response.
    public function ignore_all() {
       $response = new AjaxResponse();
       $user = \Drupal::currentUser();
       $uid = \Drupal::currentUser()->id();
       $result = views_get_view_result('recent_activity', 'rest_export_1');
       foreach($result as $value){
	    // Get a node storage object.
	     $entity = \Drupal::entityTypeManager()->getStorage('node');
	     // Load a single node.
	     $entity = $entity->load($value->nid);	
	     $flag_id = 'ignore';
	     $flag_service = \Drupal::service('flag');
	     $flag = $flag_service->getFlagById($flag_id);
	     if (!$flag->isFlagged($entity, $user)) {
		// Unflag the entity for user $account.
		 $flag_service->flag($flag, $entity);
        return $response->addCommand(new ReplaceCommand('#target-element', 'Ignore All'));

donaldp’s picture

When used outside a form, for example in an ajax call, the form radios and checkboxes do not quite work as expected. They need an additional call to expand them otherwise the radio or checkbox form elements are missing. See the following example in an ajax callback used to replace some radio elements.

  public function ajaxNewOptions(array &$form, FormStateInterface $form_state) {
    $form['test_selection'] = [
      '#type' => 'radios',
      '#title' => $this->t('Replaced options'),
      '#options' => array('1' => $this->t('Option 1'), '2' => $this->t('Option 2'), '3' => $this->t('Option 3')),
      '#prefix' => '<div id="options-replace">',
      '#suffix' => '</div>',
//    Checkboxes::processCheckboxes($form['test_selection'],$form_state,$form);

    $response = new AjaxResponse();
    $response->addCommand(new ReplaceCommand('#options-replace',$form['test_selection']));
    return $response;

with of course, the appropriate use clause:

use Drupal\Core\Render\Element\Checkboxes;
use Drupal\Core\Render\Element\Radios;

ouelmart’s picture

does any one have a more exhaustive list of events than
* Clicking a button
* Pressing a key
* Moving the mouse

and their machine name?


susannecoates’s picture

I too would like to know where to find this information.

vaninv’s picture

It's very simple. You should use DOM Events (here the full list https://www.w3schools.com/jsref/dom_obj_event.asp)

'event' => 'keyup', // <- write event here

One thing. Ommit prefix on. Use click, keyup, select instead of onclick, onkeyup e.t.c.

GaëlG’s picture

If you simply use the "use-ajax" system on a link, make sure to attach core/drupal.ajax to your render array. See https://www.drupal.org/docs/8/creating-custom-modules/adding-stylesheets...

subhojit777’s picture

You have to attach core/jquery.form and core/drupal.ajax libraries to the form, just adding the class use-ajax-submit is not sufficient.

I have opened an issue related to this [#2897120]

joegl’s picture

To use certain commands in the AJaxResponse object returned for an AJAX callback on "use-ajax" links, you need to attach the library to the render array. For example, if I want a link to open a modal:

render array

$content = array(
        '#type' => 'link',
        '#title' => t('Open Modal'),
        '#url' => Url::fromRoute('mymodule.open_modal_link'),
        '#attributes' => [
          'class' => ['use-ajax'],
      $content['#attached']['library'][] = 'core/drupal.dialog.ajax';  // needs library to open modal successfully


  path: '/ajax/open_modal_link'
    _controller: 'Drupal\mymodule\OpenModalLink::ajaxCallback'


public static function ajaxCallback() {
    $response = new AjaxResponse();

    $modal_options = array(
      'width' => 700,
    $response->addCommand(new OpenModalDialogCommand('Open Modal', 'Succesfully opened modal', $modal_options));

    return $response;

If you were to try and run the response without attaching the 'core/drupal.dialog.ajax' library to the render array it would not work.

ALTERNATIVELY, I have discovered you can also attach the library to the response itself, instead of the render array:

public static function ajaxCallback() {
    $response = new AjaxResponse();

    // add library for ajax.dialog
    $attachments = array();
    $attachments['library'][] = 'core/drupal.dialog.ajax';

    $modal_options = array(
      'width' => 700,
    $response->addCommand(new OpenModalDialogCommand('Open Modal', 'Succesfully opened modal', $modal_options));

    return $response;

I find it curious adding the command doesn't automatically include the library it would need. Also, I wrote above code out by hand, so copy-paste probably won't work.

jlballes’s picture

Something strange happened me... I had implemented a simple ajax link, like nehapandya55 did: https://api.drupal.org/comment/62887#comment-62887

And everything was working well until I enabled SSL in my local environment. After that, when I clicked in my ajax link the browser redirected me to the ajax URL and showed me the response in a textarea...

I tried several solutions like force only https in my local, and finally I installed Secure Login module (https://www.drupal.org/project/securelogin) and set it with "Submit all forms to secure URL" and "Redirect form pages to secure URL". Suddenly my ajax link worked!

Someone knows, why?
Thanks in advanced.

liquidcms’s picture

Is there support for any sort of js "hook" so that client side can pass info back to the form opened in a modal? I have a set of links with modal attrs set and jq code which has a mouseup event which does a .click() on one of these links. I need to pass info back from the jq script to the form which is opened in the modal.