‘One long debug story’ or ‘checkbox.onclick’

Hey folks

I spent another working day debugging something simple

I work on a legacy project which has many approaches that are discouraged nowadays.

The problem I tried to solve was around checkboxes. The very simplified version of the code looks like

<input id="abc" type="checkbox" onclick="someWeirdLogic()">
function someWeirdLogic() {
    var str = makeSynchronousAjaxPostback(); // don't ask me why it is synchronous... legacy...
    // and here str is
    // "document.getElementById('abc').checked = true";
    // or 
    // "document.getElementById('abc').checked = false";
    // depending on some server-side logic
public string WeirdResponse(bool currentAbcValue)
    bool newValue = !currentAbcValue;
    return string.Format("document.getElementBydId('abc').checked = {0}", newValue.ToString().ToLower());

I know it is weird…
But previously it was working…

Now I had to implement a new requirement. Under some conditions you click on the checkbox it should not become ticked

So I implemented

public string WeirdResponse(bool currentAbcValue)
    bool newValue = DoSomeAdditionalCheck(currentAbcValue);
    return string.Format("document.getElementBydId('abc').checked = {0}", newValue.ToString().ToLower());

But I found that my checkbox is being ticked on and off ignoring this logic.

Then I tried to modify the HTML to skip built-in checkbox click behavior

<input id="abc" type="checkbox" onclick="someWeirdLogic(); return false;">

And now my checkbox is not being ticked at all also ignoring the server-side logic.

I thought maybe there are some other code where my checkbox checked state is being modified and I tried to use the approach I described in my recent post.

So I kinda set a breakpoint on checkbox checked property setter to see what code makes it unchecked.

But that setter was firing only once with true value and when I stopped on the breakpoint, the checkbox was ticked. But later on when I released the debugger, checkbox became unticked again. WTF?!

I did not know what’s going on and tried many-many hours trying here and there. You can imagine that the real code was way more complicated so I spent some time debugging the server-side code first…

And after many hours I realized what’s going on.

We can see this behavior in a much simpler form without going server-side and eval.

<input id="abc" type="checkbox" onclick="document.getElementById('abc').checked = true; return false;">

You can try it http://output.jsbin.com/jidibotaku/

Actually your checkbox is not ticked even if onclick handler explicitly said to make it checked.

And the trick here is to use delayed execution.

<input id="abc" type="checkbox" onclick="setTimeout(function() { document.getElementById('abc').checked = true; }, 0); return false;">

And this works! See it http://output.jsbin.com/sepodevino/1/

You can’t untick the checkbox anymore, but that’s what we explicitly set in onclick handler.

Damn! That was not easy to find at all.

Stay tuned

About mnaoumov

Senior .NET Developer in Readify
This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s