Add GET support to AJAX callbacks in forms

Created on 15 September 2023, 10 months ago
Updated 26 October 2023, 8 months ago

Problem/Motivation

While this issue ( https://www.drupal.org/project/drupal/issues/956186 📌 Allow AJAX to use GET requests Fixed ) 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);
         });
       }
✨ Feature request
Status

Active

Version

10.1 ✨

Component
Ajax  →

Last updated 1 minute ago

Created by

🇬🇧United Kingdom altcom_nh

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @altcom_nh
  • 🇬🇧United Kingdom altcom_nh
  • 🇬🇧United Kingdom altcom_nh
  • Open in Jenkins → Open on Drupal.org →
    Environment: PHP 8.1 & MariaDB 10.3.22
    last update 10 months ago
    29,477 pass
  • Open in Jenkins → Open on Drupal.org →
    Environment: PHP 8.1 & MariaDB 10.3.22
    last update 10 months ago
    Custom Commands Failed
  • 🇬🇧United Kingdom altcom_nh

    I 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:

        // Origin
        $form['origin'] = [
          '#type' => 'select',
          '#title' => $this->t('Origin'),
          '#options' => ['' => '- Choose -'] + $origins
          '#required' => true,
          '#attributes' => [
            'class' => [
              'no-error',
            ],
            'data-ajax-type' => 'get',
          ],
          '#ajax' => [
            'disable-refocus' => TRUE, // Or false to re-focus on the triggering element.
            'event' => 'change',
            'progress' => [
              'type' => 'throbber',
              'message' => $this->t('Updating ...'),
            ],
            'url' => Url::fromRoute('custom_module.origin_callback.get'),
            'options' => ['query' => ['ajax_form' => 1]],
          ],
        ];
    

    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.

  • 🇮🇳India _utsavsharma

    Fixed failures in #2 for 9.5.x.

  • last update 8 months ago
    30,341 pass
Production build 0.69.0 2024