0

I have an input field with ajax call (filling some other input fields) on blur and buttons with click events (some of the click events set input fields to an empty string).

For example,

 $("#input_field1").on('blur', function () {
                $.ajax({
                  //async:false,
                  method: "GET",
                  url: "my_ajax.php",
                  cache: false,
                  dataType: "json",
                  data: { data1: $("#input_field1").val()},
                  success: function(result){
                        $("#some_other_input").val(result.data2);
                    }
                })
            });
$("#button1").on('click', function () {
                $("#input_field1").attr("readonly", true);
                var form = $("#my_form");
                form.validate().resetForm();
                form[0].reset();//form contains #some_other_input
            });

When that input field is focused and then user clicks on any button, blur event is triggered and of course, appropriate click event after it. If I don't use async:false, ajax will fill those input fields after click event is processed and other inputs will be filled instead of being empty.

Reading about how async:false should be avoided always, I need a way for my click events to wait until ajax is done, if there is an ajax call at that moment.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
  • First A in AJAX stands for Asynchronous. What exactly do you want to do? – Walk Oct 09 '17 at 09:28
  • You need to *embrace* async rather than fight with it. This might mean reconsidering how events work together or possibly disabling buttons while processing or it might mean you need to put up a 'please wait' style block. – freedomn-m Oct 09 '17 at 09:37
  • Disabling button while processing ajax will result in click event not firing. I really need user to be able to click on a button right after input_field1 is filled. – Julija Damjanovic Oct 09 '17 at 09:45
  • Thanks to https://stackoverflow.com/a/9151413/4805705 I managed to avoid firing blur if a mousedown event on some button is fired, because mousedown is triggered before blur. It still remains unanswered how to check if any AJAX request is being processed, wait for them to be done and then proceed with event (without using async;false). – Julija Damjanovic Oct 09 '17 at 10:19

1 Answers1

0

You need a concurrency check for your cases. On your blur action; check and set a value to prevent reentering the other calls.

Also during an ajax request, you need to prevent clicking the buttons.

One more thing, what if just after bluring your input field, user re-focuses and re-focusouts your input? In this case, your action will be triggered twice.

As a result, you need to handle concurrency. There are also some javascript libraries to handle concurrency, you can either use them or handle by your own.

Anyway to handle your case, here is a sample code:

let hasCall = false;

$("#input_field1").on('blur', function () {
   if(hasCall){
     return; //there is an active call...
   }else{ 
     hasCall = true;
     $("#button1").prop('disabled', true);//prevent clicking on button
   }
   $.ajax({
     //async:false,
     method: "GET",
     url: "my_ajax.php",
     cache: false,
     dataType: "json",
     data: { data1: $("#input_field1").val()},
     success: function(result){
       $("#some_other_input").val(result.data2);
     }
   }).always(()=>{
      //reset the state:
      hasCall=false;
     $("#button1").prop('disabled', false);
   });
});
$("#button1").on('click', function () {
   $("#input_field1").attr("readonly", true);
   var form = $("#my_form");
   form.validate().resetForm();
   form[0].reset();//form contains #some_other_input
});
ykaragol
  • 6,139
  • 3
  • 29
  • 56
  • Thank you for your answer. if just after bluring your input field, user re-focuses and re-focusouts input will not cause problem because the input will have the same value so new ajax request will not be an issue. In your code there is no enabling button and it is impossible for user to click on a button if input_field1 was focused. In my comment to my own question I explained how I managed to resolve this conflict using mousedown event, which uses in some way simillar logic to yours: setting variable to true on mousedown of the button, but not if there is or is not ajax call. – Julija Damjanovic Oct 09 '17 at 11:26
  • It is not preventing clicking the button while input was focused. It is preventing clicking the button just before the ajax request has started and re-enable it just after the ajax request has finished. – ykaragol Oct 09 '17 at 11:37