So, I have one more small problem with JavaScript in my current project: JS events do not fire in the order in which I expect them.
Say I have a text box with an onBlur event that raises an AJAX call that does some computation on the server (I use .NET 3.5 WebServices with JSON). His callback method fills a page with full text fields with calculation results.
I also have a button with an onClick event that triggers another calculation, but relies on having finished the onBlur (s) text box before the results of its onClick event are valid.
I have a simple mutex that works quite well, until the following situation: The user changes the value in one of the text fields, but has not left it yet, so the focus is still in the text field. Although the text field has focus, they push the button with the onClick event. Most often, the browser (IE7 in this case) fires the onClick event of the button before the onBlur event of the text field!
This leads to some chaos, and I do not know how to ensure compliance with the order of dismissed events. My little mutex works as follows: when any of the events occurs, I set a flag that means “wait for the callback”. Any subsequent events that will check the flag before doing anything. In the a reset callback, the flag is false.
So, any ideas? I guess I almost want all web service calls to be synchronous, but I don't know if there is an easy way to do this.
Other things I tried, or things you should know: - Disabling buttons in onBlur text fields - their onClicks still work before they are disabled - Keep in mind this only happens when editing a text field and immediately clicking a button . If the user clicks on an empty space to launch the onBlur of the text field before clicking the button, everything works fine.
EDIT:
After some comments and more testing here, what I would like to do:
In the onBlur of the text box, I want to disable the button so that its onClick event does not fire. However, when I code this, the onBlur event occurs, I see that the button is disabled, but the onClick event still fires.
. onClick, . setTimeout 500 , , . , ...
<html>
<head>
<script type="text/javascript">
var onClickFlag = false;
function whatHappensOnFocus(el) {
log('whatHappensOnFocus(): TextField focused.');
onClickFlag = false;
log('whatHappensOnFocus(): Set onClickFlag = false');
}
function whatHappensOnBlur(el) {
log('whatHappensOnBlur(): TextField blurred.');
document.getElementById('theButton').disabled = true;
log('whatHappensOnBlur(): Disabled the Button');
setTimeout(function() { someTestFieldFunction(); log('whatHappensOnBlur(): OnBlur callback called: someTestFieldFunction()'); }, 50);
log ('whatHappensOnBlur(): setTimeout for someTestFieldFunction() for 50ms');
}
function log(msg) {
document.getElementById('log').value += ('[' + (new Date().getTime()).toString() + '] ' + msg + '\n');
}
function someTestFieldFunction() {
log('someTestFieldFunction(): Inside someTestFieldFunction()');
log('someTestFieldFunction(): Test: onClickFlag = ' + onClickFlag);
setTimeout(enableButton, 50);
log('someTestFieldFunction(): setTimeout for enableButton()');
}
function enableButton() {
document.getElementById('theButton').disabled = false;
log('enableButton(): Button re-enabled');
}
function whatHappensOnClick(el) {
log('whatHappensOnClick(): the Button onClick fired');
someFunction();
log('whatHappensOnClick(): someFunction() called');
}
function whatHappensOnMouseDown(el) {
log('whatHappensOnMouseDown(): inside whatHappensOnMouseDown()');
onClickFlag = true;
log("whatHappensOnMouseDown(): set onClickFlag = true");
}
function someFunction() {
log('someFunction(): inside someFunction()');
log('someFunction(): You have successfully clicked the button');
}
</script>
</head>
<body>
<form id="testform">
<input type="text" size="10" onfocus="whatHappensOnFocus(this);" onblur="whatHappensOnBlur(this);" />
<br />
<br />
<input id="theButton" type="button" onmousedown="whatHappensOnMouseDown(this);" onmouseout="onClickFlag = false;" value="calculate" onclick="whatHappensOnClick(this);" />
<br />
<br />
<textarea rows="15" cols="100" id="log" style="overflow: scroll"></textarea>
<input type="reset" value="clear" />
</form>
</body>
</html>
UPDATE:
, , , , . , onMouseDown onBlur . - , , . callback onSuccess AJAX, onBlur , , ( , ) ( , ). , , , .