34

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.

  • Mmmm...morning project :) – Lester Peabody May 18 '12 at 13:14
  • What's the time period that you need this done within? – Lester Peabody May 18 '12 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 May 18 '12 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 May 23 '12 at 3:22
  • 1
    #random - :-o I thought @Clive was all about answers, you even ask questions ;) :D – SGhosh May 6 '14 at 14:50
42
+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);
});
  • 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 May 18 '12 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 May 19 '12 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 May 19 '12 at 11:45
  • @Clive, I'm very happy the solution found :) – kalabro May 19 '12 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 Jun 3 '13 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);
  • Awesome! I'm glad that worked out for you. – Chance G May 21 '12 at 0:18
  • How is this done on Drupal 6? – Ryan G May 28 '13 at 8:17
  • really great, but applies once only :) – Kojo Jul 4 '14 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

  • That looks great thanks a lot :) I'll get it installed and post some comments on the review when I get a chance – Clive May 24 '12 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.

  • 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 May 18 '12 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 May 18 '12 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 May 18 '12 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. – Lester Peabody May 18 '12 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 May 18 '12 at 14:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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