views:

256

answers:

2

EDIT: I wrongly assumed this was caused by blockUI(); I was using Firebug's console.log to log the message but for the example here I changed to alert so you wouldn't need firebug to replicate. Once I tested it again, I was able to remove blockUI and the onclick didn't fire not firing. The issue seems to be whenever the DOM is changing or feedback given it stop the onclick from firing.

I am having issues with jQuery blockUI plugins and firing two events that are (I think, unless I am loosing it) unrelated.

Basically I have textboxes with onchange events bound to them. The event is responsible for blocking the UI, doing the ajax call and on success unblocking the UI. The ajax is saving the text in memory. The other control is a button with on onclick event which also block the UI, fire an ajax request saving what's in memory to the database and on success unblock the UI.

Both of these work fine separately. The issue arise when I trigger the onchange by clicking on the button. Then only the onchange is fired and the onclick is ignored.

I can change the text in the checkbox, click on the link and IF jQuery.blockUI() is present (or an alert) the onchange alone is fired and the save is never called. If I remove the blockUI (or an alert) both function are called.

Here's a fully working example where you can see the issue. Please note the setTimeout are there when I was trying to simulate the ajax delay but the issue is happening without it.

To replicate type something in the textbox and click save. Both event should be firing but only the onchange is triggered.

<html>
<head>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"&gt;&lt;/script&gt;
    <script src="http://github.com/malsup/blockui/raw/master/jquery.blockUI.js?v2.31"&gt;&lt;/script&gt;
    <script>
        function doSomething(){
            //$.blockUI();
            alert("doing something");
            //setTimeout(function(){
                //$.unblockUI();
            //},500);
        }

        function save(){
            //$.blockUI();
            console.log("saving");
            //setTimeout(function(){
            //$.unblockUI();
            //}, 1000);
        }

    </script>
</head>

<body>
    <input id="textbox" type="text" onchange="doSomething();">
    <a id="link" href="#"onclick="save()">save</a>
</body>
</html>
A: 

There's only going to be one event loop going at any given time in the environment of a single page. If your ajax calls are synchronous, then while one event is being handled then that's all the will be going on. If the browser were to trigger another event loop, well, then it wouldn't be single-threaded. But it is, so it doesn't.

Pointy
I removed the ajax call from the example and used an alert instead which produce the same result (the second event not firing). Your explanation make sense since the alert is waiting for user input hence blocking the thread...but shouldn't the next event be queued?
jfrobishow
well that's up to the browser ...
Pointy
Then wouldn't onfocus cause the same thing?, as you can see in my other post onfocus is fired.
jfrobishow
Try changing the onclick handler from just `save()` to `save(); return false`
Pointy
Same thing, the onclick doesn't appear to be triggered at all. I've also tried returning true in doSomething() and adding a return true; to the onchange handler...to no avail.
jfrobishow
Well it works fine for me. Using your exact code, it works fine. Both the onchange and the onclick handler are called.
Pointy
Which browser are you using? I tried this in Firefox 3.6.4 and the latest Chrome on XP. Weird!
jfrobishow
OK now I see what you're saying - I had commented out the "alert()" in "doSomething" for some reason I don't remember. When I un-comment that, I see the following: type in a text field and tab out - doSomething is called. Type in a text field then click the `<a>` - doSomething is called, but the save() is not called.
Pointy
Well I don't understand why it happens. It seems that an alert() call from the "change" event handler is just dropping the "click" event completely. I've copied my test version of your code out to http://gutfullofbeer.net/so.html so you can play with it. If the alert() is disabled, then both event handlers get called.
Pointy
IE8, Chrome, and Firefox all behave exactly the same way, for whatever that's worth.
Pointy
Thanks for the "live" example so that it's easier to play with for everyone. I've noticed the same, all browsers behave the same way as if it's expected behavior. Doesn't make any sense though, I would expect onfocus to work the same way and be dropped yet it isn't.
jfrobishow
A: 

The following "fixed it" using onfocus for the link and the event is triggered. With an onclick it isn't.

This work:

<html>
<head>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"&gt;&lt;/script&gt;
    <script src="http://github.com/malsup/blockui/raw/master/jquery.blockUI.js?v2.31"&gt;&lt;/script&gt;
    <script>
        function doSomething(){
            alert("blocking UI");
            console.log("do something");
            //alert("doing something");
            //setTimeout(function(){
                //$.unblockUI();
            //},500);
        }

        function save(){
            //$.blockUI();
            console.log("saving");
            //setTimeout(function(){
            //$.unblockUI();
            //}, 1000);
        }

        function cachebtn()
        {
            console.log("cache bouton");
        }
    </script>
</head>

<body>
    <input id="textbox1" type="text" onchange="doSomething();">
    <input id="textbox2" type="text" onchange="doSomething();">
    <a id="link" href="#" onfocus="save()">save</a>
</body>
</html>

This doesn't, the only different is the onclick which isn't firing when the onchange precedes it.

<html>
<head>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"&gt;&lt;/script&gt;
    <script src="http://github.com/malsup/blockui/raw/master/jquery.blockUI.js?v2.31"&gt;&lt;/script&gt;
    <script>
        function doSomething(){
            alert("blocking UI");
            console.log("do something");
            //alert("doing something");
            //setTimeout(function(){
                //$.unblockUI();
            //},500);
        }

        function save(){
            //$.blockUI();
            console.log("saving");
            //setTimeout(function(){
            //$.unblockUI();
            //}, 1000);
        }

        function cachebtn()
        {
            console.log("cache bouton");
        }
    </script>
</head>

<body>
    <input id="textbox1" type="text" onchange="doSomething();">
    <input id="textbox2" type="text" onchange="doSomething();">
    <a id="link" href="#" onclick="save()">save</a>
</body>
</html>
jfrobishow