I'm working on a custom module and one of the fields it has on its settings page is an AJAX button configured as follows:

$form['target_directory_group']['row']['check_directory_button'] = [
   '#type' => 'button',
   '#value' => $this->t('Check Target Directory'),
   '#ajax' => [
      'callback' => '::ajaxPathValidator',
	  'effect' => 'fade',
	  'progress' => [
               'type' => 'throbber',
               'message' => t('Checking directory...'),
            ],
      '#validate_target' => 'target_directory',
      '#validate_type'   => 'directory',
      '#validate_wrapper'=> '#directory-status',			
   ],
   '#attributes' => ['class' => ['button--primary', 'my-inline-field', 'my-icon-button'],],
];

$form['target_directory_group']['description'] = [
   '#type' => 'markup',
   '#markup' => '<div class="form-item__description">'.$this->t('Enter the full path of the directory.'.'</div>',
];

What I'm trying to figure out is how to modify the AJAX button's throbber location.

Right now, whenever I click on the AJAX button, I see the little twirling throbber icon with "Checking directory..." displayed in a DIV, and I want to have better control of where that gets displayed. For example, I'd like to take that completely out of where it gets printed in the markup to be placed somewhere else on the page, hopefully targeted by using an element's class and or ID as a means of indicating precisely where.

It seems as if there's 2 different contexts in Drupal's AJAX when something gets printed on the page:

1.) When the button is pressed, it displayed the "progress" message. THIS IS THE THING I'M WANTING BETTER CONTROL OVER.

2.) When a response is retrieved from the callback, which can be displayed in a provided "#validate_wrapper," which is separate from the throbber. This, I DO NOT want to change.

Can the throbber / progress indication that an AJAX button prints upon being pressed, have its position modified? If so, how? Is it something that can only be changed in JavaScript / behaviors? Because so far, I haven't really found any clear explanation on how to do it by way of the Form API (PHP).

One of the biggest reasons I'd like to change the location that it's printed / displayed at is because whenever the throbber / progress indication is displayed, it "crunches" the fields it's next to and causes the entire field's width to momentarily shrink. (It just looks unprofessional, and being able to relocate it outside of that and better-control how it's displayed in terms of location, etc., would look better.)

Thanks in advance.

Comments

wolf_22’s picture

In time (and with some ChatGPT consultation), I eventually found a way to make this happen:
 

1.) In the render array for the AJAX button, give the "progress" element a type of "none."

2.) Create an exclusive throbber override markup render array that has a type of "markup" with the "#markup" element containing something like the following:

<div class="ajax-progress" style="display:none;">
	<div class="ajax-progress__throbber">&nbsp;</div>
	<div class="ajax-progress__message">Processing...</div>
</div>

3.) Style the throbber with some CSS, namely by applying styles to .ajax_progress and .ajax-progress__throbber.

4.) You'll then go into your behaviors and create a click event handler, which is the part I'm currently working on with my implementation as this is where it seems trickiest as I haven't yet found a very clean way to isolate the originating element responsible for the AJAX. But it's in the behaviors that you'll show or hide the contents that the AJAX button controls.

And make sure to clear the cache (Drupal AND browser) as you develop it.

Hope this helps.