Problem/Motivation

Currently ajax.js places the following after the element that has triggered a loading action:
<div class="ajax-progress ajax-progress-throbber"><div class="throbber">&nbsp;</div></div>

This is terribly hard to modify or replace with your own loading animation, it's a UI pattern that is very dated and causes many layout issues as it changes the flow of the document.

Proposed resolution

Replace the element inserted with a class that is added to the element that triggers the loading action. The current behaviour can be replicated perfectly using a CSS pseudo element. Using a class instead increases the flexibility of the action in CSS without having to wade through any Drupal specific code. A button could change text or animate. I would also like to add a class to to the body of the page during loading, this would make full screen loading animations easier, a very common UI pattern.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

LewisNyman’s picture

I've attached a patch which outlines my intentions

jwilson3’s picture

Totally agree with this. Theming / overriding the throbber style and location should be trivially easy to do.

Sometimes you want the throbber to reside inside the button itself that is clicked... while other times you may need to position the throbber elsewhere on the page, or display a full-screen overlay to block further input. The patch in #1 makes the first part possible; a follow-up patch that adds a body class (and possibly a companion empty top-level dom element?) would make the later stupid simple. Not to blow the scope completely here, but having an encapsulated way to simply override the throbber javascript in your theme without touching the entire ajax.js file would be clever as well.

jwilson3’s picture

Encapsulating the throbber js and css code to allow it to be overridable by a theme is a good candidate for the theme component library.

amen’s picture

Status: Active » Needs work
FileSize
1.55 KB

Here's a first shot at tackling this problem and come up with an usable, extensible way to deal with throbbers.

It replaces the html chunk that got appended to "throbbing" elements with a class named throbbing. I chose this name to make it consistent with what the Autocomplete widget uses.

There's no styling on it yet, but I guess it's a matter of coding css now if this approach gets pushed.

LewisNyman’s picture

Status: Needs work » Needs review

Go testbot

Status: Needs review » Needs work
Issue tags: -Needs themer review, -TX (Themer Experience), -Theme Component Library

The last submitted patch, ajax-throbber-class-1490402-4.patch, failed testing.

amen’s picture

Status: Needs work » Needs review
Issue tags: +Needs themer review, +TX (Themer Experience), +Theme Component Library

#4: ajax-throbber-class-1490402-4.patch queued for re-testing.

amen’s picture

Added CSS for the following elements:

  • a
  • .button
  • input[submit]

Also, untested RTL styling is available.

jwilson3’s picture

Issue summary: View changes

Added links to related issues.

LewisNyman’s picture

I've noticed that the edit module uses a class instead, we might be better off conforming everything to the same design for now.

LewisNyman’s picture

Issue summary: View changes
Issue tags: +JavaScript, +CSS
LewisNyman’s picture

I did some more work on this patch and included the gif from the edit module, which is more inline with the ajax loader that ctools uses anyway.

There are some clear situations where this technique is more fragile and get's overridden by some special styling, like on the manage fields page. I think this disadvantage is part and parcel of the technique. The idea is to give themer more control over their loading state UI elements. It does mean we will have to go in and write specific styling against special UI elements that are now broken.

Opinions?

amen’s picture

In D7 and below, in order to change the styling on the throbber, you either have to hack the core or do some very weird css/jquery shennenigans. I know this because once I lost like 3 days trying to come up with the best solution for a client of mine who requested it.

So being able to be style the throbber just by overriding a single class is exactly why I would like this patch to be pushed. If you need me to work on some other patch for other elements tha don't work anymore please link the issues here and I will be happy to do it.

LewisNyman’s picture

Just realised I never posted the patch. How embarrassing! A review against existing use cases would be great.

Status: Needs review » Needs work

The last submitted patch, 13: ajax-throbber-class-1490402-10.patch, failed testing.

LewisNyman’s picture

Status: Needs work » Needs review
FileSize
5.69 KB

I should of seen that coming.

LewisNyman’s picture

Status: Needs review » Needs work

The last submitted patch, 15: ajax-throbber-class-1490402-15.patch, failed testing.

The last submitted patch, 15: ajax-throbber-class-1490402-15.patch, failed testing.

sun’s picture

The implementation was recently revised in #1069152: Throbber in textfield is misaligned when browser hardware acceleration enabled (gfx)

As a followup to that I suggested #2181399: Consider moving the animated .GIF throbber outside the autocomplete fields and using CSS animation instead. — which might be a duplicate of some of the related issues.

I'm not sure what the exact deal is here, but in general, "CSS class" sounds good ;)

LewisNyman’s picture

Status: Needs work » Needs review
FileSize
11.04 KB
159.77 KB
167.76 KB

I've rerolled this patch and gone over the use cases for the throbber in core. It looks pretty good!

droplet’s picture

  1. +++ b/core/modules/edit/css/edit.theme.css
    @@ -246,11 +246,24 @@
    +.edit-button.action-save.is-loading {
    

    the throbber.gif is very low quality. It looks very bad on blue background.

  2. +++ b/core/modules/system/css/system.module.css
    @@ -4,6 +4,52 @@
    +  background-image: url(../../../misc/throbber.gif);
    ...
    +  height: 18px;
    +  width: 19px;
    

    It's not a big problem but not sure if we possible to find an icon exactly square in size (18 x 18)

Outi’s picture

FileSize
57.09 KB

I tested this with the latest patch, and on the content type editing form the throbber looks good (as in the previous screenshots) but on the view editing form (and probably on the other dropbuttons) it's half outside of the button.

Concerning the blue background: it's true that the throbber.gif looks very bad on a dark background (to see it: create and save a node > click on the contextual link to quick edit it > make a modification > click Save), and for instance I haven't found a .gif throbber that would look good both on a white and on a colored background. (I don't know if it's possible. Should we use two different throbbers depending on the background?)

By the way, the edit module uses this throbber already (named icon-throbber.gif), so even without the patch the throbber looks bad in the quick edit form. Perhaps we should anyway unify the different throbbers used, as the Views_ui uses still another throbber, loading.gif and loading-small.gif, that has a dark background.

rteijeiro’s picture

Status: Needs review » Needs work

Let's try to get more feedback about what @Outi asked in previous comment.

Outi’s picture

Should the throbber question be resolved in another issue and use here the existing throbber?

LewisNyman’s picture

I think we should use the existing throbber, the edit module already looks bad, so we are not introducing anything new.

steven.grimaldo’s picture

LewisNyman, what admin theme is that in your screenshots?

LewisNyman’s picture

@steven.grimaldo That's Seven :D

LewisNyman’s picture

Bojhan’s picture

Lets change the icon in a separate issue, because it is a little bit tricky. The style guide does define one, so I think its best to follow that as a guidance.

lauriii’s picture

Status: Needs work » Needs review
FileSize
11.16 KB

Rerolled patch #20. Ready for more testing.

jwilson3’s picture

Issue for changing the icon here: #1974928: Update throbber icon

Status: Needs review » Needs work

The last submitted patch, 30: ajax-throbber-class-1490402-30.patch, failed testing.

andrejsmuzikovs’s picture

Issue tags: +frontendunited

Rerolling this soon!

andrejsmuzikovs’s picture

Assigned: Unassigned » andrejsmuzikovs
rteijeiro’s picture

Issue tags: -frontendunited +FUDK

It seems official tag is FUDK (kinda weird, BTW)

andrejsmuzikovs’s picture

Rerolled. Was only one conflict in core/modules/quickedit/css/quickedit.icons.css

andrejsmuzikovs’s picture

Status: Needs work » Needs review
joelpittet’s picture

+++ b/core/themes/seven/css/style.css
@@ -918,6 +918,19 @@ textarea.form-textarea {
+input.form-autocomplete.is-loading,
+input.form-text.is-loading,
+input.form-tel.is-loading,
+input.form-email.is-loading,
+input.form-url.is-loading,
+input.form-search.is-loading,
+input.form-number.is-loading,
+input.form-color.is-loading,
+input.form-file.is-loading,
+textarea.form-textarea.is-loading,
+select.form-select.is-loading {

Is there any input that this will not work on? Maybe a input:not() would be easier to maintain?

andrejsmuzikovs’s picture

Assigned: andrejsmuzikovs » Unassigned
droplet’s picture

+++ b/core/misc/ajax.js
@@ -461,11 +461,10 @@
     else if (this.progress.type === 'throbber') {

@@ -478,9 +477,7 @@
-    if (this.progress.element) {
-      $(this.progress.element).remove();
-    }
+    $(this.element).removeClass('is-loading');

Shouldn't add a condition to avoid the code execution on all ajax calls, eg:

if (this.progress.type === 'throbber')
...
..

Status: Needs review » Needs work

The last submitted patch, 37: ajax-throbber-class-1490402-37.patch, failed testing.

amen’s picture

Rerolled the Patch manually.

I tried to mimic the way the progress bar is set up, by adding a Throbber Class in progress.js and creating the instances in ajax.js.

I also consolidated the css from this patch with other css that has been added since this issue started.

I think the next step would be nice to replace throbber-active.gif with a css3 animated .svg, similar to what autocomplete has.

amen’s picture

Status: Needs work » Needs review
droplet’s picture

good idea but i think we should rewritten the function into Mixin pattern. (more re-usable & less duplicated code)

amen’s picture

Assigned: Unassigned » amen
Status: Needs review » Needs work
LewisNyman’s picture

@droplet A mixin? We don't have mixins available to us

+++ b/core/themes/seven/css/components/buttons.theme.css
@@ -54,6 +54,30 @@
+  background: url(../../../../misc/throbber-active.gif) no-repeat 95% center,
+  -webkit-linear-gradient(top, #f6f6f3, #e7e7df);
+  background: url(../../../../misc/throbber-active.gif) no-repeat 95% center,
+  -moz-linear-gradient(top, #f6f6f3, #e7e7df);
+  background: url(../../../../misc/throbber-active.gif) no-repeat 95% center,
+  -o-linear-gradient(top, #f6f6f3, #e7e7df);
+  background: url(../../../../misc/throbber-active.gif) no-repeat 95% center,
+  linear-gradient(to bottom, #f6f6f3, #e7e7df);

Looks like we don't need to provide gradient prefixes any more, so we can remove a lot of code here - http://caniuse.com/#feat=css-gradients

droplet’s picture

@LewisNyman,

Sorry, i'm not speaking clearly. It's programming side designs pattern. Not the CSS Preprocessor function. :)

jwilson3’s picture

So now there is a movement to introduce HiDPI-compliant SVG files across core, which presents problems with the purely class-based background image rotation technique.
Simply put, the only way to animate/rotate SVG elements is using CSS transitions (like how progress bar currently works). But with a purely class-based solution, we cannot get a rotating throbber when used as a background image inside autocomplete form elements. We really need a standard DOM based solution (much like progress bar) that adds the appropriate DOM elements after the item in question.

I think we should re-open #2181399: Consider moving the animated .GIF throbber outside the autocomplete fields and using CSS animation instead. and focus on getting one single standardized way to add this throbber to the page that fully supports the hi-res/scalable SVG image animation.

Finally, the ideas proposed in #2407859: Allow theming throbber element could solve a lot of the original issues with the throbber being completely inaccessible to themers. I think there might be some useful code on the last patch here that could combine forces with that issue to provide themable throbbers.

jwilson3’s picture

Issue tags: +HiDPI

Tagging because this is semi-related and affected by HiDPI (see prev comment).

jwilson3’s picture

Edit: remove double comment posted.

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

mattshoaf’s picture

I came across this issue regarding theming the ajax throbber, looks like it has came to a halt (nothing for 3 years), but I found this Ajax Loader contrib module that I think solves the issue for themers. As a developer inspecting the code it's provides an example of what you could do if you need something more custom.

lauriii’s picture

Is this still a problem after #2407859: Allow theming throbber element has been solved?

Phil Wolstenholme’s picture

Hi @lauriii – I think this could still be an issue I think, or maybe a spin off issue? Although now we're less likely to use CSS pseudo content to add markup/spinners etc (because of #2407859), people might still want to use a general 'is-loading' CSS class on the body to do things like disable a button when an AJAX event is going on.

From the original issue description

A button could change text or animate. I would also like to add a class to to the body of the page during loading, this would make full screen loading animations easier, a very common UI pattern.

A .is-loading or similar class would mean we could do something like the below to discourage users from clicking a button twice while an AJAX event is still pending.

.is-loading .my-fancy-button {
  filter: grayscale(100%);
  pointer-events: none;
  opacity: 0.8;
  background-image: url(spinner.gif);
  background-repeat: no-repeat;
  background-position: left;
}
rgpublic’s picture

+1, a class would be *very* useful in many cases I've experienced. I also think the class should not only be added to the body but also to the respective view, because there might be multiple views on the page and you might want to selectively show loading animations etc. This would make it possible, for example, to easily gray out the corresponding exposed form while the AJAX view is loading etc. Stuff like that is currently really hard to do because you are only left with that fixed element which is inserted at a fixed position and which you might not even want there.

I'm currently working around that by directly listening for jQuery's ajaxBefore/ajaxComplete events, trying to detect when a view is loading etc. It's really complicated, because ajaxBefore/ajaxComplete events are triggered by *ANY* ajax happening on the page. A simple class that is automatically added to the view container would make all this infinitely simpler.

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

andypost’s picture

Version: 8.9.x-dev » 9.3.x-dev
Issue tags: -JavaScript +JavaScript

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.