Skip to content
mnaoumov.dev
Go back

'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
    eval(str);
}
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


Share this post on:

Previous Post
Funny Out-of-memory error
Next Post
How to debug JavaScript to find code which modifies your DOM