Checkbox inside an anchor click behavior

nkrkv picture nkrkv · Nov 11, 2011 · Viewed 10.2k times · Source

Consider following snippet:

<!DOCTYPE html>
<html>
    <head>
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
    </head>
    <body>
        <form>
            <a id="a" href="http://google.com">Goooooogle</a>
        </form>
        <script>
            $(function() {
                var checkbox = $('<input type="checkbox"></input>');
                checkbox.prependTo($('#a'));
                checkbox.click(function(e) {
                    e.stopPropagation();
                    // do something useful
                });
            });
        </script>
    </body>
</html>

I want to get a checkbox inside <a>, and get following on-click behavior:

  1. Toggle check mark normally as usual
  2. Do something useful like AJAX-request
  3. Stay on this page, i.e. not be redirected to an a href

Also I want to not override default behavior if I click anywhere in a, but not on checkbox. I.e. I want to allow to execute all event handlers associated with a click itself.

I thought that should be pretty easy, but I can't get desired behavior. Either:

  • I get redirected to Google if I put a code provided.
  • I don't get check mark toggled if I use e.preventDefault() of return false;. Furthermore in that case checkbox ignores explicit checkbox.attr('checked', 'checked') and all other possible ways to set the check mark.

Where is the catch?

UPD: This works as expected in Chrome, e.g. I'm not redirected on click, but fails in Firefox. Is there cross-browser way?

Answer

nkrkv picture nkrkv · Nov 12, 2011

Well, it looks like a known Firefox bug, which leads to following link on checkbox click regardless of handlers' code. As a bit dirty workaround one can use:

var checkbox = $('<input type="checkbox"></input>');
checkbox.prependTo($('#a'));
checkbox.click(function(e) {
    setTimeout(function() { checkbox.prop('checked', !checkbox.prop('checked')); }, 10);       
    // do something useful on clicking checkbox and but not surrounding link
    return false;
});