0

Here's my problem: when the user clicks on the "validate" button, I send an AJAX request that returns an array of "problematic" elements. From that array, I compute the id of the elements I want to highlight then I "flash" them.

This is nice, it works, but they all flash together.

I want to flash them one after the other, so that it's longer and looks nicer (= not aggressive). I've spent some time trying to use queue() function (I guess it's the way to go) but didn't manage to make it work.

Any idea how to do this?

/* this is the function to retrieve bg color (= not the actual subject) */
jQuery.fn.getBg = function() {
    return $(this).parents().filter(function() {
        var color = $(this).css('background-color');
        return color != 'transparent' && color != 'rgba(0, 0, 0, 0)';
    }).eq(0).css('background-color');
};

/* this is my flash function (= not the actual subject) */
function flash(id, font_color, bg_color, nb) {
    var bc=$(id).getBg();
    var cl=$(id).css('color');
    var mx=parseInt(nb);
    if (mx<=0) {
        mx=1;
    }
    for (var i=0; i<mx; i++) {
        $(id).animate({
            backgroundColor: bg_color,
            color: font_color
        }, 200)
        .animate({
            backgroundColor: bc,
            color: cl
        });
    };
}

function localOnAjaxError(dataMessage)
{
  var msg='';
  $('#wait').hide('slow');
  /* show the form again and highlight errors */
  $('#s-inscrire-form').show('slow', function() {
    if (msg!='') {
      $('#erreur').fadeIn('slow');
      flash('#erreur', "#f9e4c9", "#aa0000", 3);
    }
    if (dataMessage instanceof Array) {
      for (key in dataMessage) {
        var m=dataMessage[key];
        if(m.indexOf('#error')==0) {
          /* show the id... */
          $(m).fadeIn('slow', function() {
            /* ...then flash the corresponding label */
            flash('#label-'+this.id.substr(7), "#ffffff", "#aa0000", 3);
          });
        }
      }
    }
  });
  seConnecterAssigneClicksConnexion();
}
Filburt
  • 17,626
  • 12
  • 64
  • 115
Olivier Pons
  • 15,363
  • 26
  • 117
  • 213

3 Answers3

0

You will need to return the animation queue from your flash function. Then, instead of starting all flashes together in your for-loop (btw: for-in-loops are not suited for arrays), you will need to push them recursively on that queue. What have you tried with .queue()?

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
0

You would be correct to use jQuery's queue method. Here's an example that takes all divs and changes their color in sequence.

var theQueue = $({});

$('div').each(function(index, div) {
    theQueue.queue('flash', function(next) {    
        $(div).animate({
            backgroundColor: 'red'
        }, 500, function() {
            next();
        });    
    });
});

theQueue.dequeue('flash');

Live example - http://jsfiddle.net/z7xRe/

There's another question on Stack Overflow that walks through this use case in more detail here - What are queues in jQuery?. See @gnarf's response.

Community
  • 1
  • 1
TJ VanToll
  • 12,584
  • 4
  • 43
  • 45
  • Thank you very much indeed, but, relying on your sample I've tried to make it work but it doesn't, see here: http://jsfiddle.net/k8yKP/1/ – Olivier Pons May 25 '12 at 19:03
  • To do color animations you need to include jQuery UI as well (see http://jqueryui.com/demos/animate/). I clicked the checkbox to bring in jQuery UI on your jsFiddle and it works as expected - http://jsfiddle.net/78zar/. – TJ VanToll May 25 '12 at 19:07
  • Ok, now I'm facing the last problem: when elements are in an array. http://jsfiddle.net/k8yKP/2/ => sorry, when it comes to JavaScript I'm not the sharpest tool in the shed .. – Olivier Pons May 25 '12 at 19:30
  • Here's my stuff with console.log() added, I don't know how to make it work: http://jsfiddle.net/k8yKP/3/ – Olivier Pons May 25 '12 at 19:39
  • I've added the working solution, thank you for putting me on the right track! – Olivier Pons Jun 04 '12 at 19:04
0

Here's the working solution:

dataMessage = new Array("#erreur-nomprenom", "#erreur-adresse1", "#erreur-cp", "#erreur-ville", "#erreur-tel");
var theQueue = $({});
for (key in dataMessage) {
    var m = dataMessage[key];
    if (m.indexOf('#erreur') == 0) {
        var toFlash = (function(m) {
            return function(next) {
                $(m).fadeIn('slow', function() {
                    flash('#label-' + this.id.substr(7), "#ffffff", "#aa0000", 3);
                    next();
                });
            }
        })(m);
        theQueue.queue('flash', toFlash);
    }
}
theQueue.dequeue('flash');
Olivier Pons
  • 15,363
  • 26
  • 117
  • 213