1

I update three inputs in a row, they are updated sequentially via a single button click and I do a cool color change (glowing) effect to each input after completion of updating:

You should see something like this where t= time (i feel like a scientist)

    [30.20]  [20.32]  [34.33]  [Update] <--- Clicked this
t=1 Glow
t=2          Glows     
t=3                   Glows

but sometimes the color effect goes out of order like:

    [30.20]  [20.32]  [34.33]  [Update] <--- Clicked this
t=1 Glow
t=2                   Glows
t=3          Glows     

Here is my script:

FYI: i tested and found that the out of sequence issue begins on the .each

On the page they are one after the other.

function UpdatePrice(TheButton, Type) {
    $(TheButton).parent().parent().find("input").each(function (index, element) {

        $.ajax({
            cache: false,
            data: { ByContractID: $(element).parent().attr("id"), Cost: $(element).val(), ItemType: Type },
            type: "Post",
            url: '@Url.Action("UpdateCost")'
        }).success(function () {

            $(element).next().html(($(TheButton).parent().parent().children("td").eq(0).html() * $(element).val()).toFixed(2));
            $(element).val(parseFloat($(element).val()).toFixed(2));
            var old = $(element).css('background-color');
            $(element).animate({ "background-color": "#D2F0C9" }, "fast", function () { $(element).animate({ "background-color": old }, "fast") });


        });


    });

    return false;
}

What do y'all think?

Thanks!

Pinch
  • 4,009
  • 8
  • 40
  • 60

2 Answers2

2

You're doing an ajax request, and each request can take different amounts of time... Since ajax is asynchronous, they all execute at the same time, which one returns first outputs first, etc..

Erik Funkenbusch
  • 92,674
  • 28
  • 195
  • 291
2

Try using a Queue like in my answer here, then you can do something like this:

function UpdatePrice(TheButton, Type) {
    var q = new Queue;
    $(TheButton).parent().parent().find("input").each(function (index, element) {
        //add to the Queue
        q.add(function(){
            $.ajax({
                cache: false,
                data: { ByContractID: $(element).parent().attr("id"), Cost: $(element).val(), ItemType: Type },
                type: "Post",
                url: '@Url.Action("UpdateCost")'
            }).success(function () {

                $(element).next().html(($(TheButton).parent().parent().children("td").eq(0).html() *     $(element).val()).toFixed(2));
                $(element).val(parseFloat($(element).val()).toFixed(2));
                var old = $(element).css('background-color');
                $(element).animate({ "background-color": "#D2F0C9" }, "fast", function () {     $(element).animate({ "background-color": old }, "fast") });

                q.next(); //run next function

            });

            return false; 
            // ^^ insures that the queue does not continue when the function is finished.
        });

    });

    return false;
}

The reason why you have to do this is because Ajax is asynchronous, so in order to run them in order, you have to run the new ajax call after the previous one is finished.

Community
  • 1
  • 1
Naftali
  • 144,921
  • 39
  • 244
  • 303
  • Uncaught ReferenceError: Queue is not defined – Pinch Jul 11 '13 at 19:49
  • @Pinch did you add the `Queue` class from my [previous answer](http://stackoverflow.com/a/17528961/561731)? – Naftali Jul 11 '13 at 19:50
  • @Pinch No problem ^_^ Happy I can help. The `Queue` object can be used in many many different ways. I am sure you will find ways to expand it :-D – Naftali Jul 11 '13 at 19:53