6

My original post caused some confusion, so I'm re-writing it for clarity.

In Drupal, if you have an #ajax callback in a form, you can do something like this:

function my_ajax_callback(array &$form, FormStateInterface $form_state)
{
  $response = new AjaxResponse();
  $response->addCommand(new AlertCommand(t('This is from an ajax callback'));
  return $response;
}

This in turn triggers Drupal.ajaxCommands.prototype.alert(), which is located in ajax.js.

Alternatively, I can create an ajax callback of my own, that has nothing to do with a form. example.routing.yml:

mymodule.ajax
  path: '/mymodule/ajax'
  defaults:
    _controller: 'Drupal\my_module\Controller::ajaxCallback'
  # (remainder not shown)

I can create an AjaxResponse in this callback:

class Controller extends ControllerBase
{
  public function ajaxCallback()
  {
    $response = new AjaxResponse();
    $response->addCommand(new AlertCommand(t('This is from an ajax callback'));
    return $response;
  }
}

In this case, debugging has shown me that the AjaxResponse returns my command to the browser, but Drupal.ajaxCommands.prototype.alert() is not triggered.

Further debugging has shown me that ajax commands are only triggered if the AjaxResponse comes from an #ajax callback in a form, not if it's from a non-form ajax callback.

So my question is, does anyone know how to invoke ajax commands when the commands are returned from non-form ajax callback?

6

Like @Gaius I don't know exactly what @Jaypan wants to achieve. This example might help to make this clearer:

        var response = JSON.parse(content);
        // Create a Drupal.Ajax object without associating an element, a
        // progress indicator or a URL.
        var ajaxObject = Drupal.ajax({
          url: '',
          base: false,
          element: false,
          progress: false
        });
        // Then, simulate an AJAX response having arrived, and let the Ajax
        // system handle it.
        ajaxObject.success(response, 'success');

Normally you set an URL in Drupal.ajax() and then use ajaxObject.execute() to run the Ajax request. This example from big_pipe.js only simulates the Ajax request and then runs the Ajax commands contained in content.

  • That was it! Exactly what I needed. Thank you. I also re-wrote my question to make it clearer exactly what I was asking. – Jaypan Jan 28 '17 at 2:28
  • 1
    For anyone who wants to see a real example of this, you can check out the Fancy Login module, in which I implemented this technique. The functions to checkout in particular are: 1) The $.ajax trigger in /js/fancy_login.js in the function(). 2) The ajax callback in /src/Controller/FancyLoginController ajax_callback() [which I will be renaming as ajaxCallback() in the next release of the module]. – Jaypan Jan 28 '17 at 3:30
3

It might not be related and is also a rather old post, but for anybody like myself desperately searching for some hint on the Drupal 8 ajax api:

Drupal.ajax({url: '/some/url'}).execute().done(
    function(comands, statusString, ajaxObject){
        console.log("we're done ;-)");
})

This tutorial might also be helpfull: https://www.thirdandgrove.com/rendering-view-ajax-drupal-8

0

If your Ajax request is triggered by a link, just add the "use-ajax" CSS class to your link. And remove all the JS manually added for sending your Ajax request. It will be automatically handled by drupal.ajax .

The problem is on the front end side. Drupal return an Ajax response, but JS doesn't know it and just do nothing with it.

  • After another read of your post, I'm not sure my answer is what you need... Don't hesitate to comment it. – Gaius Jan 27 '17 at 6:44
  • Thanks, but it wasn't what I was looking for - I've re-written my original post for clarity. – Jaypan Jan 28 '17 at 2:17

Your Answer

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

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