jiwopene
jiwopene

Reputation: 3637

Checkbox on mousedown, uncheck on mouseup

I am making jQuery application where there is a checkbox that is checked only when the mouse/key/touch is pressed. Check on mousedown, uncheck on mouseup.

Even if I use event.preventDefault(), the checkbox remains checked if the mouse button is not down, but the spacebar works fine.

$(function() {
  var cb = $("input");
  cb
    .on("mousedown keydown", function(event) {
      event.preventDefault();
      cb.prop("checked", true);
    })
    .on("mouseup keyup", function(event) {
      event.preventDefault();
      cb.prop("checked", false);
    });
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<input type=checkbox autofocus>

I know the code above needs a bit of work to work correctly in any situation (touch, etc.) but it is written for testing purposes only

Upvotes: 1

Views: 1554

Answers (1)

Rory McCrossan
Rory McCrossan

Reputation: 337627

The issue is because the click event fires when mouseup is released on the checkbox and this forces the checked property to true. To fix this hook an event handler to the click and simply call preventDefault() on it.

Also note that you can provide an object to on() which is keyed by the event names you want to hook to, instead of calling on() multiple times:

$(function() {
  var $cb = $("input");
  $cb.on({
    "mousedown keydown": function(e) {
      e.preventDefault();
      $cb.prop("checked", true);
    },
    "mouseup keyup": function(e) {
      e.preventDefault();
      $cb.prop("checked", false);
    },
    'click': function(e) {
      e.preventDefault();
    }
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<input type=checkbox autofocus>

Alternatively, as @enapupe pointed out in the comments, you could remove the mouseup event handler entirely and let the default click event run as normal to toggle the state of the checkbox:

$(function() {
  var $cb = $("input");
  $cb.on({
    "mousedown keydown": function(e) {
      e.preventDefault();
      $cb.prop("checked", true);
    }
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<input type=checkbox autofocus>

Either will work, it just depends on the behaviour you want to have with regard to suppressing the click event

Upvotes: 3

Related Questions