TIMEX
TIMEX

Reputation: 272214

How do I solve this problem in JQuery?

$("#id_address_input").bind("blur",function(e){
    //do a lot of stuff, set variables.
});

So, I have a text box that when the user gets off of it...this thing gets fired and processes.

Ok, the problem is this:

When the user clicks the form Submit button, this blur thing gets fired. And in the middle of processing, the form submits. This messes everything up.

How do I fix this? I thought about adding a delay on form.submit, so that it'll finish processing. But, that's a bad idea because I haven idea how fast the user's browser and/or Google Maps is.

Upvotes: 1

Views: 173

Answers (3)

T.J. Crowder
T.J. Crowder

Reputation: 1075269

In your blur handler, you must be doing something that "yields" to the browser (a setTimeout, an asynchronous ajax call, etc.), because otherwise, the browser will not interrupt your JavaScript code to submit the form. See below for an example proving it.

If you are doing something that yields to the browser from within the blur handler, you'll have to prevent the form submission with a submit handler and then have it get submitted when everything (including the various actions in the blur handler) is ready. This may be a bit complicated.

The best answer is to remove whatever it is in the blur handler that's yielding to the browser. If you can't do that, you're probably looking at a locking counter on the form and having the submission handler check that locking counter:

// Somewhere, ensure the form has a lock count of zero
$('#theForm').data('submitlock', 0);

// Your blur handler increments the lock
// In the blur handler:
$('#theForm').data('submitlock', $('#theForm').data('submitlock') + 1);
// ...and when done
$('#theForm').data('submitlock', $('#theForm').data('submitlock') - 1);

// The submit handler might look something like this:
$('#theForm').submit(function() {

    // Get a jQuery wrapper for the form
    var $this = $(this);

    // Locked?
    if ($this.data('submitlock') > 0) {
        // Yes, set up the recheck and prevent form submission
        setTimeout(recheck, 10);
        return false;
    }

    // Function to periodically retry submission
    function recheck() {
        // Still locked?
        if ($this.data('submitlock') > 0) {
            // Keep waiting
            setTimeout(recheck, 10);
        }
        else {
            // Nope, submit the form using the underlying DOM object's submit function
            $this[0].submit();
        }
    }
});

Live example (a version of our blocking example below, but updated to yield to the browser)

Beware that if your form is being submitted to a new window, you may run afoul of pop-up blockers (since the new window isn't in direct response to a user click). But if you're not doing something like that, you're in good shape with the above.


Here's an example of a blur handler causing a substantial delay (four seconds) before the form is submitted (live copy):

HTML:

<form action='http://www.google.com/search' target='_new'>
  <label>Search for:
    <input type='text' name='q' value='foo'></label>
  <br><input type='submit' value='Search'>
</form>

JavaScript:

$('input[name=q]').blur(function() {

  var end, counter;

  display("Start blurring");
  counter = 0;
  end = new Date().getTime() + 4000;
  while (new Date().getTime() < end) {
    ++counter;
    if (counter % 100000 == 0) {
      display("Still blurring");
    }
  }
  display("Done blurring");

});

Put your cursor in the text box, and then click Search. You'll see a four-second delay, and then the search will open in a new window. I've tested this on Chrome, Firefox, and Opera (on Linux), IE6 on Windows 2000, and IE7 on Windows XP. All behaved the same way.

Upvotes: 1

mauris
mauris

Reputation: 43619

Try a flag?

var doSubmit = true;

$("#id_address_input").bind("blur",function(e){
    doSubmit = false;
    //do a lot of stuff, set variables.
    doSubmit = true;
});

$("#form").submit(function(){
    if(doSubmit){
        return true;
    }else{
        // keep checking until doSubmit is true
        window.setInterval(function(){if(doSubmit){$("#form").submit();}},1000);
        return false;
    }
});

Upvotes: 1

sushil bharwani
sushil bharwani

Reputation: 30197

Do your form submit using javascript. Write a function which calls on onsubmit and check to see if the things that were supposed to happen on blur event have finished. Then only submit your form

Upvotes: 1

Related Questions