4

I want to serialize 2 events in my web application. I have change event tied to an input field and click event tied to a button. User sometimes enters value is input field and presses button immediately.

I want that change event should be called before click event.

Both of the events have AJAX calls and I have declared change event AJAX call as synchronous, but this does not help.

EDIT: Other important details are as follows I am using jQuery UI autocomplete feature related change event for input field.

Here is the portion of html code along with related javascript code

<!-- I have more than one input fields with class set as code -->
<input type="text" name="code_1" id="code_1" class="code" value=""/>
<input type="text" name="code_2" id="code_2" class="code" value=""/>
<input type="text" name="code_3" id="code_3" class="code" value=""/>

<!-- Here is the clickable button -->
<input type="button" value="Save" class="formButton" id="postCharge"/>

// Here is the javascript code for these items

$(".code").autocomplete({
    source: jsHrefRoot+"/ajax/cpt_autocomp.php",
    minLength: 3,
    delay: 500,  // milliseconds - 1s = 1000ms
    select: function (event, ui) {
      $(this).val(ui.item.id);
      return false;
    },
    change: function (event, ui) {
    // Following function has an AJAX call
      getCodeDetail($(this));
      return false;
    }
  }).each(function(){
    // This part is for rendering each item and not relevant to my question
  });


 $( "#postCharge" ).click(function(){
    // Again there is an AJAX call in this fuction after long logic of input validation
})

3 Answers 3

2

Here is one (async) way:

var $codeInputs = $('.code');
var $button = $('#postCharge');

function changeHandler (cb) {
    $.ajax({
        // ...
        complete: function () {
            $(this).data('changeHandled', true);
            cb();
        }
    });
}

function clickHandler () {
    $.ajax({
        // ...
    });
}

function checkChanges (cb) {
    var $unhandled = $codeInputs.filter(function () {
        var hasChanged = $(this).val() !== $(this).data('initialValue');
        return hasChanged && !$(this).data('changeHandled');
    });

    if (!$unhandled.length) return cb();

    changeHandler.call($unhandled.first().get(), checkChanges.bind(this, cb));
}

$codeInputs.each(function () {
    $(this).data('initialValue', $(this).val());
})
.autocomplete({
    // ...
    change: function (event, ui) {
        changeHandler.call(this.get(), function () {
            // Ajax call complete
        });
    }
});

$button.click(function (e) {
    e.preventDefault();
    checkChanges(clickHandler.bind(this));
});
Sign up to request clarification or add additional context in comments.

Comments

0

I delayed click event to wait for completion of autocomplete change.

function postCharges() {
  ...
  }
  $( "#postCharge" ).click(function(e){
    e.preventDefault();
    setTimeout(postCharges, 1000);
  });

Comments

-1

change event always fire before click.

var cansubmit =true;
$('text').on('change',function(){
    cansubmit = false;
    $.ajax({
        ...
        complete:function(){
            cansubmit = true;
        }
    })
}
buildPromise=function(){
    new Promise(function(resolve,reject){
        var timer = null;
        function checkCanSubmit(){
            if(cansubmit){
               clearInterval(timer);
               resolve();
            }
        }
        if(cansubmit)
              resolve();
        else
              timer = setInterval(checkCanSubmit,10);
    })
}
$('btn').on('click',function(){
    buildPromise().then(function(){
        //todo::
    })
})

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.