简体   繁体   中英

Adding a delay to JQuery keyup() after Ajax call

I'm having a quite tough problem and I'm not sure how to approach it. I have a few textboxes in a row and I need to fill in these textboxes. Every time a textbox is filled, I grab the value and make an Ajax call that uses the value. The response determines whether or not that very textbox is colored red or green(using the Jquery css() function).

Now here's the problem. Let's say I have 5 textboxes in a row. Let's say I type 1-tab, 2-tab, 2-tab, 1-tab, 1-tab. All of this very fast. 1-tab, for example, means I type 1 followed by the Tab button to move to the next textbox. I realized that if I go too fast, some of the textboxes don't get updated and their colors do not change. I assumed this is due to the ajax taking some time to process.

I thought about the problem and came up with an idea that might solve the problem. That is add a delay after each Ajax call and then tab to the next. I search around SO and found this solution . However, it's not really working for me(basically it breaks and the JS doesn't work at all).

Here's a snippet of my AJAX. I stripped it down and removed the unnecessary pieces of code.

$( ".myTextbox" ).keyup(function() {
        //Defining my variables here

        $.ajax({    
            //Perform First Ajax request

            $.ajax({   
                //Perform Second Ajax Request
            });  

        });
});

Here's the solution I tried using what I found from SO, but it doesn't work.

var timer = null;
$( ".myTextbox" ).keyup(function() {
        clearTimeout(timer);

        timer = setTimeout(
            function(){
                .ajax({    
                //Perform First Ajax request                        
                    $.ajax({   
                        //Perform Second Ajax Request
                    });                  
                });
            }, 200);
        //Defining my variables here
});

Now, there are 2 options:

  1. My logic is wrong about delaying the tab key. Could there be some better logic to overcome my initial problem?

  2. I'm using the solution posted above wrongly.

Hope to get some constructive answers.

Thanks.

EDIT: Here's the full code, upon request.

$( ".getqty" ).keyup(function() {
    var split = this.id.split(":");
    var color = split[0];
    var size = split[1];
    var prodID = split[2];
    var $this = $(this);
    var value = $this.val();
    var stock = 0;
    var price = split[3];
    var originalProd = split[4];
    var dataStock = $this.attr("data-stock");
    if(value.length > 0){
        value = parseInt(value);
    }else{
        value = "";
    }

    $.ajax({    //create an ajax request 
        type: 'POST',
        url: 'includes/add.php',             
        dataType: 'html',   //expect html to be returned   
        data:'color='+color+'&size='+size+'&prodID='+prodID+'&qty='+value+'&originalProd='+originalProd+'&dataStock='+dataStock,     
        success: function(response){   
            if(response == "breakOut"){              
                   $this.css('background-color', '#F87171').css('border', '1px solid #B42C2C');  
                   $("#"+originalProd+"-"+color).text("Not enough in stock.").css('color', '#B42C2C');   
                   $("#"+originalProd+"-totalPrice").text("");
            }else{
                stock = response;
                if((value > 0 && value <= stock) || (value > 0 && dataStock == 'yes')){
                        $this.css('background-color', '#66CF66').css('border', '1px solid #277230');                        
                }else{
                    $this.css('background-color', '#fff').css('border', '1px solid #ccc');
                }   

                var count = 0;
                $("."+color+"-" + originalProd).each(function(){
                        if($(this).val() == 0){
                            count = count + 0;
                        }else{
                            count = count + parseFloat($(this).val(), 10);
                        }
                });

                //Single Item Total
                if(count > 0){
                    var totalPrice = (price * count).toFixed(2);
                    $("#"+originalProd+"-"+color).text(count + " - " + totalPrice.toString().replace(/\./g, ',') + " Eur").css('color', '#CCC');
                }else{
                    $("#"+originalProd+"-"+color).text("");
                }


                $.ajax({    //create an ajax request
                    type: 'POST',
                    url: 'includes/cart.php',             
                    dataType: 'html',   //expect html to be returned   
                    success: function(response){                   
                        if(response > 0){
                            $("#cart_price").text("Cart: "+response.toString().replace(/\./g, ',')+ " Eur");
                        }else{
                            $("#cart_price").text("Cart:0,00 Eur");
                        }                            
                    },
                    error:function (xhr, ajaxOptions, thrownError){
                    // alert(thrownError);
                    }
                });  
                if(pathname == 'mycart.php'){
                    location.reload();
                }                  
            }
        },
        error:function (xhr, ajaxOptions, thrownError){
         //alert(thrownError);
        }
    });

You should use the change event instead of keyup. From the docs:

The keyup event is sent to an element when the user releases a key on the keyboard. It can be attached to any element, but the event is only sent to the element that has the focus.

When you press tab your elements will change focus quickly and maybe the keyup event will not be fired for that input text with the right value content.

So try:

$( ".getqty" ).change(...)

Update: Since the change event just fires when the input text loses focus, you could write instead:

$( ".getqty" ).on('input', function() {
  var $this = $(this);
  var value = $this.val();

  if (value.length > 0) {
    value = parseInt(value);
  }
  else {
    value = "";
  }

  $.ajax({
    type: 'POST',
    url: 'data.txt',             
    dataType: 'text', 
    success: function(response){   
      $this.css('background-color', '#66CF66').css('border', '1px solid #277230');                        

      $.ajax({
        type: 'POST',
        url: 'data.txt',             
        dataType: 'text', 
        success: function(response){                   
          $("#cart_price").text("Cart: "+response.toString().replace(/\./g, ',')+ " Eur");                          
        },
        error:function (xhr, ajaxOptions, thrownError){
          console.log(thrownError);
        }
      });                 
    },
    error: function (xhr, ajaxOptions, thrownError){
     console.log(thrownError);
    }
  });
});

Or with pure javascript event listeners:

var elemList = document.getElementsByClassName('getqty');
for (var i = 0; i < elemList.length; i++) {
  elemList[i].addEventListener('input', function(e) {
    var $this = $(e.target);
    var value = $this.val();

    if (value.length > 0) {
      value = parseInt(value);
    }
    else {
      value = "";
    }

    $.ajax({
      type: 'POST',
      url: 'data.txt',             
      dataType: 'text', 
      success: function(response){   
        $this.css('background-color', '#66CF66').css('border', '1px solid #277230');                        

        $.ajax({
          type: 'POST',
          url: 'data.txt',             
          dataType: 'txt', 
          success: function(response){                   
            $("#cart_price").text("Cart: "+response.toString().replace(/\./g, ',')+ " Eur");                          
          },
          error:function (xhr, ajaxOptions, thrownError){
            console.log(thrownError);
          }
        });                 
      },
      error: function (xhr, ajaxOptions, thrownError){
       console.log(thrownError);
      }
    });
  });
}

You can try this to delay on keyup

$('input').keyup(function() {
    delay(function(){
      alert('Time elapsed!');
    }, 1000 );
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM