Quantcast
Channel: Issues for Drupal core
Viewing all articles
Browse latest Browse all 292894

JavaScript AJAX commands object is borked: it is shared among all Drupal.ajax instances, preventing scoped overrides

$
0
0

as shown in #1678002: Edit should provide a usable entity-level toolbar for saving fields the way our ajax commands are implemented is wrong.

our docs say:

/**
* Ajax object.
*
* All Ajax objects on a page are accessible through the global Drupal.ajax
* object and are keyed by the submit button's ID. You can access them from
* your module's JavaScript file to override properties or functions.
*
* For example, if your Ajax enabled button has the ID 'edit-submit', you can
* redefine the function that is called to insert the new content like this
* (inside a Drupal.behaviors attach block):
* @code
*    Drupal.behaviors.myCustomAJAXStuff = {
*      attach: function (context, settings) {
*        Drupal.ajax['edit-submit'].commands.insert = function (ajax, response, status) {
*          new_content = $(response.data);
*          $('#my-wrapper').append(new_content);
*          alert('New content was appended to #my-wrapper');
*        }
*      }
*    };
* @endcode
*/

This is good, this is what everyone expects. But it's a lie.

What happens is that Drupal.ajax.prototype.commands = {} is a single object shared by all ajax objects. What was ment is something like Drupal.ajax.prototype.commands.prototype = {} (don't try it at home that's not where we want to end up). When you follow the docs, you don't override one command from the one ajax object you're working with, you override the command for all ajax objects ever.

what we need is

Drupal.ajax = function () {
  this.commands = new Drupal.AjaxCommands();
};

Drupal.AjaxCommands = function () {};  // empty, on purpose
Drupal.AjaxCommands.prototype = {/* the old command object */};

and now the doc is right.

HAI I DO JAVASCRIPT!


Viewing all articles
Browse latest Browse all 292894

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>