Problem/Motivation
While this issue (https://www.drupal.org/project/drupal/issues/956186) added GET support for ajax links it missed out adding the same support for AJAX callbacks.
Steps to reproduce
Any ajax callback created using the forms API will make a POST request, even with the data attribute added. This is because the code added to the js to allow the default POST method to be overridden is only added to Drupal.ajax.bindAjaxLinks = function (element) {...} in misc/ajax.js
The ajax callback form elements are initialised in function loadAjaxBehavior(base) { at the start of the file.
Proposed resolution
Add the 'same' code to the function setting up the ajax callbacks for form elements as has been added to ajax links.
E.g.
diff --git a/core/misc/ajax.js b/core/misc/ajax.js
index 739c67046d..6cb7cc42c2 100644
--- a/core/misc/ajax.js
+++ b/core/misc/ajax.js
@@ -42,8 +42,16 @@
// Use jQuery selector instead of a native selector for
// backwards compatibility.
once('drupal-ajax', $(elementSettings.selector)).forEach((el) => {
+ const $element = $(el);
elementSettings.element = el;
elementSettings.base = base;
+ const httpMethod = $element.data('ajax-http-method');
+ /**
+ * In case of setting custom ajax http method for callback we rewrite ajax.httpMethod.
+ */
+ if (httpMethod) {
+ elementSettings.httpMethod = httpMethod;
+ }
Drupal.ajax(elementSettings);
});
}
| Comment | File | Size | Author |
|---|---|---|---|
| #5 | 3387616-5.patch | 1.43 KB | _utsavsharma |
| #5 | interdiff_2-5.txt | 828 bytes | _utsavsharma |
| #2 | 3387616-ajax-callback-using-get-d9_5_x.patch | 1.54 KB | altcom_neil |
| #2 | 3387616-ajax-callback-using-get.patch | 800 bytes | altcom_neil |
Comments
Comment #2
altcom_neil commentedAttached is a patch for Drupal 10.1.x and one for 9.5.x
Comment #3
altcom_neil commentedComment #4
altcom_neil commentedI guess I have found why this hasn't been done before. It is not the simple case of adding the support to initiate the callbacks to use GET instead of POST by mimicking what was done for links.
While it looks like all the JavaScript libraries are being added to the AjaxResponse object, the
add_js: function add_js(ajax, response, status)call in core/mis/ajax.js throws the "LoadJS" error from the core/assets/vendor/loadjs/loadjs.min.js file when attempting to load any libraries that weren't already loaded.In our case we were creating a form with an ajax field with a url:
The Controller for this route then updated a second select field with a list destinations with a ReplaceCommand, and returned a MessageCommand. It is the 'core/drupal.message' library that is in the list of attached libraries with the AjaxResponse but throws the error trying to load it. Which then leads to a further js error when the message call
message: function message(ajax, response)tries to call 'new Drupal.Message()'.This could be a trivial or a complicated fix requiring more patches, I don't have any familiarity with any of the Ajax system, nor the time to investigate any further so will have to give up on adding this functionality for now.
=============================================================================
EDIT - I don't know if this is an issue now. Part of the scope of work was was also adding the patch from https://www.drupal.org/project/drupal/issues/3348789 to compress the ajax_page_state query parameter. Removing this allows this code to work and I believe what was going on was that the 'LoadJs' error is due to trying to load js libraries that have already been added. So I think the error is in the patch for the compress issue.
Comment #5
_utsavsharma commentedFixed failures in #2 for 9.5.x.