Prevent checkbox from ticking/checking COMPLETELY

I have been asked to disable the "ticking" of a checkbox. I am not being asked to disable the checkbox, but to simply disable the "ticking".

In other words, a user will think that a checkbox is tickable, but it is not. Instead, clicking on the checkbox will cause a modal dialog to appear, giving the user more options to turn on or off the feature that the checkbox represents. If the options chosen in the dialog cause the feature to be turned on, then the checkbox will be ticked.

Now, the real problem is that for a split second, you can still see that the checkbox is being ticked.

I have tried an approach like this:

<input type='checkbox' onclick='return false' onkeydown='return false' />

$('input[type="checkbox"]').click(function(event) {
    event.preventDefault();
    alert('Break');
});

If you run this, the alert will appear, showing that the tick is visible (the alert is just there to demonstrate that it still does get ticked, in production, the alert is not there). On some users with slower machines and/or in browsers with slow renderers/javascript, users can see a very faint flicker (the flicker sometimes lasts for half a second, which is noticeable).

A tester in my team has flagged this as a defect and I am supposed to fix it. I'm not sure what else I can try to prevent the tick in the checkbox from flickering!


Solution 1:

Try

event.stopPropagation();

http://jsfiddle.net/DrKfE/3/

Solution 2:

Best solution I've come up with:

$('input[type="checkbox"]').click(function(event) {
    var $checkbox = $(this);

    // Ensures this code runs AFTER the browser handles click however it wants.
    setTimeout(function() {
      $checkbox.removeAttr('checked');
    }, 0);

    event.preventDefault();
    event.stopPropagation();
});

Solution 3:

From my point of view it is as simple as:

$(this).prop('checked', !$(this).prop('checked'));

Works both for checked and unchecked boxes

Solution 4:

This effect can't be suppressed I fear. As soon as you click on the checkbox, the state (and rendering) is changed. Then the event handlers will be called. If you do a event.preventDefault(), the checkbox will be reset after all the handlers are executed. If your handler has a long execution time (easily testable with a modal alert()) and/or the rendering engine repaints before reseting, the box will flicker.

$('input[type="checkbox"]').click(function(event) {
    this.checked = false; // reset first
    event.preventDefault();
    // event.stopPropagation() like in Zoltan's answer would also spare some
    // handler execution time, but is no more needed here

    // then do the heavy processing:
    alert('Break');
});

This solution will reduce the flickering to a minimum, but can't hinder it really. See Thr4wn's and RobG's answer for how to simulate a checkbox. I would prefer the following:

<button id="settings" title="open extended settings">
    <img src="default_checkbox.png" />
</button>
document.getElementById("settings").addEventListener("click", function(e) {
    var img = this.getElementsByTagName("img")[0]);
    openExtendedSettingsDialog(function callbackTick() {
        img.src = "checked_checkbox.png";
    }, function callbackUntick() {
        img.src = "unchecked_checkbox.png";
    });
}, false);