35

I have a view with some exposed filters in a block; it uses AJAX and the auto-submit feature so the view is re-loaded as soon as a filter option is changed.

In the short delay between selecting an option and the view being re-loaded, the familiar blue AJAX throbber is shown somewhere at the bottom of the form (I think where the hidden submit button is currently located).

I know I can customise this image by overriding the CSS for the throbber element, but I'd prefer not to use it at all.

What I'd much rather do is temporarily fade out the exposed filter form (and ideally the main view as well), using a jQuery animation. They would then fade back in when the AJAX call is complete.

Failing that, I'd like to use the same method that the Views UI module uses when it's updating, namely placing this icon in the middle of the page:

enter image description here

As that is already built in I just assumed there would be a setting somewhere to change the style/location of this loading behaviour; no such luck though.

How do I implement either of these methods?

I'm using Drupal 7 with Views 7.x-3.3.

6
  • Mmmm...morning project :) Commented May 18, 2012 at 13:14
  • What's the time period that you need this done within? Commented May 18, 2012 at 14:44
  • @Lester I'm not in a massive rush as it's not a release-blocker for any of the projects I'm working on...but I must admit it's bugging me! I rarely use Views and I don't have the time (or energy frankly) to get 'involved' with it at a lower level; but as I'm now starting to port my e-commerce efforts to Drupal Commerce I need to be able to do this kind of thing. If I receive a good answer during the 7 day bounty period I'll be over the moon :)
    – Clive
    Commented May 18, 2012 at 14:51
  • Hey i just finished creating my custom module (with settings admin page) for styling the views throbber. Are you still interested? I can upload it within few days in drupal.org
    – ANDiTKO
    Commented May 23, 2012 at 3:22
  • 1
    #random - :-o I thought @Clive was all about answers, you even ask questions ;) :D
    – SGhosh
    Commented May 6, 2014 at 14:50

4 Answers 4

44
+100

If you don't mind using a little jquery you could always do something like:

$('#view-id').ajaxStart(function(){
   $('#view-filters-id').fadeTo(300, 0.5);
});
$('#view-id').ajaxSuccess(function(){
   $('#view-filters-id').fadeTo(300, 1.0);
});
6
  • 4
    Yes, I agree with this solution. Just note, that jQuery ajaxSend and ajaxComplete can be used with condition if (settings.url == '/views/ajax') {//... } for more control.
    – kalabro
    Commented May 18, 2012 at 22:39
  • Wow I really over-complicated things it seems so obvious now! I had to attach the events to the filter form rather than the view (otherwise ajaxSuccess only gets fired once; I guess because the event isn't automatically re-bound to the replaced <div>) but other than that this is perfect, not to mention beautifully simple. Thanks very much
    – Clive
    Commented May 19, 2012 at 11:44
  • @kalabro Thanks again for your help with this, if I could split the bounty between this and your answer I would; but I've got to go for this one really as it's nearly a fully working example :)
    – Clive
    Commented May 19, 2012 at 11:45
  • @Clive, I'm very happy the solution found :)
    – kalabro
    Commented May 19, 2012 at 11:50
  • 1
    As of jQuery 1.8, the .ajaxSuccess() method should only be attached to document. Comparing the settings value, as suggested by kalabro above, is the way to go. source: api.jquery.com/ajaxSuccess
    – cjoy
    Commented Jun 3, 2013 at 3:26
29

For the sake of completeness here's the code I ended up using; it fades both the exposed filter form and the view out when the AJAX load begins, and back in again when it finishes:

(function($) {
  Drupal.behaviors.events = {
    attach: function(context, settings) {
      $('#views-exposed-form-events-page', context).ajaxStart(function(){
        $('#views-exposed-form-events-page,div.view-id-events', context).fadeTo(300, 0.5);
      });
      $('#views-exposed-form-events-page', context).ajaxSuccess(function(){
         $('#views-exposed-form-events-page', context).fadeTo(300, 1.0);
         $('div.view-id-events', context).css('opacity', 0.5).fadeTo(300, 1.0);
      });
    }
  };
})(jQuery);
3
  • Awesome! I'm glad that worked out for you.
    – Chance G
    Commented May 21, 2012 at 0:18
  • How is this done on Drupal 6? Commented May 28, 2013 at 8:17
  • really great, but applies once only :)
    – Kojo
    Commented Jul 4, 2014 at 10:29
10

Hello i have created a very simple module that dose exactly what you want to do. The module has configuration page where you can control the style of the throbber and even upload your own images without any hacking.

This is the sandbox link: http://drupal.org/sandbox/ANDiTKO/1556808

If you find it useful please reveiw it here so it can be approved as official project: http://drupal.org/node/1556114

1
  • That looks great thanks a lot :) I'll get it installed and post some comments on the review when I get a chance
    – Clive
    Commented May 24, 2012 at 23:25
6

I just have made a research.
The throbber is hardcoded here in the constructor of Drupal.views.ajaxView.
An instance of Drupal.views.ajaxView is not stored in Drupal.ajax and there is @todo about it.
It means that we can't go into the object and set our own params.

How does Views it do?

The short answer is CSS.
Views admin page just hides throbber and adds style to it's parent .ajax-progress-throbber.

.ajax-progress-throbber {
  background-color: #232323;
  background-image: url("../images/loading-small.gif");
  background-position: center center;
  background-repeat: no-repeat;
  -moz-border-radius: 7px;
  -webkit-border-radius: 7px;
  border-radius: 7px;
  height: 24px;
  opacity: .9;
  padding: 4px;
  width: 24px;
}

Can I do something with Drupal.ajax?

Yes, I found some methods you can overwrite for AJAX elements (buttons, links, etc). I have showed an example here: How to extend or “hook” Drupal Form AJAX?. But in this case it will be not so good.
Progress element is showing at beforeSend stage, so you can do something before it happens.

7
  • Thanks very much for the information, but I'm not sure how I would use it to solve my problem; are you saying it's not possible to add/change the default Views ajax loading behaviour beyond CSS, at least without hacking the Views module?
    – Clive
    Commented May 18, 2012 at 14:15
  • I mean, you can use CSS, because Views uses it too. Just hide .throbber and add some styles to .ajax-progress-throbber
    – kalabro
    Commented May 18, 2012 at 14:20
  • OK, so both the exposed filter form in the block, and the view itself, get a class of .ajax-progress-throbber when any AJAX is invoked? I must admit I haven't noticed that happening but I'll check. And you reckon I'll be able to invoke jQuery animation in a beforeSend function (based on the answer to your other question)? Thanks, I don't really use Views and I can't be bothered to dig all the way down into every bit of code to find out what's happening! I'll let you know how I get on with trying that
    – Clive
    Commented May 18, 2012 at 14:28
  • 1
    Something to keep in mind to achieving the fade effect you want on the form elements, you can also utilize CSS Transitions instead of jQuery animations, though jQuery animations will work across all browsers and CSS Transitions only on the latest generation. Commented May 18, 2012 at 14:33
  • Thanks @Lester, I'd rather use jQuery for the time being. @kalabro unfortunately your suggestion doesn't work; neither the view, nor the exposed filter block, get the .ajax-progress-throbber class applied to them at any point so your method won't work. Thanks for trying though
    – Clive
    Commented May 18, 2012 at 14:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.