Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disable checkbox (material light) checking

In my app i'm using Google Material Light library.

And i do not wanna check my input (until some logic is right), that's why i added such directive:

app.directive('updLink', function () {
    return {
      restrict: 'EA',
        link: function(scope, element) {
          element.bind('click', function(evt) {
            evt = evt || window.event;
            evt.preventDefault();
            evt.stopPropagation();
            evt.returnValue = false;
            return false;
          });
        }
      };
  });

and my html:

  <label class="mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect" for="123">
      <input type="checkbox" id="123" class="mdl-checkbox__input"  ng-model="user" upd-link>
  </label>

why prevent this directive isn't working in IE10+?

checkbox is checking(

and value is changing...

is it possible to stop any changes and checking on this element?

plunker: https://plnkr.co/edit/CCQaBOntmQ4eWh0RUJ5Q?p=preview

like image 288
brabertaser19 Avatar asked Mar 18 '16 06:03

brabertaser19


1 Answers

If you're just interested in how to do this, skip to the end. If you want to know a bit about why you're having all this trouble, read on!

Why you're seeing this

It's worth noting that the reason you're seeing this is that the order of events here is different in IE to other browsers.

Basically, in Chrome (and I presume FF), the graphic update to change the checkbox to visually "checked" occurs after the onclick functions are called. In IE however, the graphic change is done first, and THEN the onclick events are called, which is why your preventDefault() and stopPropogation() calls are doing nothing - the horse has already bolted at that point. You can see this for yourself by adding an alert at the start of the bound function before evt = evt || window.event: in Chrome the box is still unchecked, in IE it is already too late.

What can you do?

Here's where it gets a bit complicated. Using ng-disabled and its ilk is only an option if you're happy that an action doesn't fire when you click the checkbox, which I don't think is what you want.

The result of this is that I don't think there's anything you can do to stop an actual click event firing on the checkbox element checking the box in IE. If you want to stop the box being checked, but the action of clicking the checkbox cause something to happen, you're going to need to either:

  1. Intercept the click in some way so that it never actually hits the element.
  2. Do something to cancel out the act of clicking.

Option 1 is a bit tricky and prone to error. I had some success with SetCapture but it was a bit inconsistent. Thankfully, option 2 provides a much simpler solution.

The Solution

Don't intercept the click, don't stop the propogation, just check the box yourself so that the second "check" in the click event unchecks it again. The end result is that your box remains unchecked to the user, and you can fire off whatever functionality you want off the back of the click event:

element.bind('focusin', function() {
  this.checked=true;
});

focusin is called just as the element is about to receive focus - i.e, being clicked. It's not perfect as if a user tabs over the checkbox it would check it, but I found that using the click event wasn't working for me. There may be a better event to use, or you may know of a way to get the click event to work. Worst case scenario you can always have the function exit with no effect if the tab key us currently pressed.

I've tried this in IE11 and Chrome, both seem to work as expected.

like image 114
Ieuan Stanley Avatar answered Sep 20 '22 11:09

Ieuan Stanley