Disabled button is clickable on Edge browser
Asked Answered
P

4

8

I have problem with Edge browser. In my web site I have buttons with span tags inside them. In this span tags I bind text and icons. So far I had no problem but on Edge browser it is possible to click on disabled buttons. After investigating problem I found out that, when button contains span tags inside, it is possible to click on button. Here is how it looks on my web site:

<button id="btnRefresh" type="button" class="btn btn-primary" ng-click="refresh()" ng-disabled="performingAction">
    <span ng-class="performingAction && action == 'refresh' ? 'fa fa-cog fa-spin' :'fa fa-refresh'"></span>
    <span>{{ refresh }}</span>
</button>

Here is example to testing:

<button type="button" disabled="disabled" onclick='alert("test");'>
    <span>Click me!</span>
</button>

One option would be to hide buttons instead of disabling, but I prefer to disable them. Please suggest solution to over come this issue.

Plasticity answered 3/9, 2015 at 13:28 Comment(4)
This appears to be a bug. I've logged it here: connect.microsoft.com/IE/feedback/details/1748050Tomas
I'm voting to close this question as off-topic because this is a bug in Microsoft EdgeAnthropophagi
@Popnoodles: That does not make the question off-topic. It's on-topic, the answer being "It's a bug". See e.g. meta.#268742 for a meta discussion.Gilolo
@Gilolo yes but you don't get enough options. The closest may be "Offtopic because... Questions about general computing hardware and software are off-topic for Stack Overflow unless they directly involve tools used primarily for programming. You may be able to get help on Super User."Anthropophagi
H
5

Just set

pointer-events: none;

for disabled buttons.

Here's CSS to disable all disabled elements everywhere:

*[disabled] {
    pointer-events: none !important;
}

pointer-events documentation

Hierophant answered 22/12, 2015 at 13:36 Comment(1)
Excellent! Why do it in Javascript if it can be done in CSS?Evin
G
3

This is a bug in Microsoft Edge. Disabled buttons accept clicks if they contain any HTML elements (i.e. if they contain anything else than just text).

Reported multiple times via Microsoft Connect:

The bug was still present in Build 10565 (16 October 2015). It was fixed in the November update, Build 10586.


A possible (but ugly) workaround is to call some Javascript in onclick for every button, which then checks if the button is disabled and returns false (thus suppressing the click event).

Gilolo answered 27/10, 2015 at 15:13 Comment(2)
I can confirm that this bug is now fixed as of Build 25.10586.0.0.Tomas
@RyanJoy: Yes - the bug you opened in Microsoft Connect (linked above) has also been closed.Gilolo
P
1

One work around I've come up with using angularjs is inspired by Ben Nadel's blog here

So for example:

angular.module('myModule').directive(
    "span",
    function spanDirective() {
        return ({
            link: function (scope, element, attributes) {
                element.bind('click', function (e) {
                    if (e.target.parentNode.parentNode.disabled || e.target.parentNode.disabled) {
                        e.stopPropagation();
                    }
                })
            },
            restrict: "E",
        });
    }
);
Pepito answered 5/11, 2015 at 14:17 Comment(1)
Forgot to add browser detection in the example, but I guess you'd need to do that. Also this will override click for all span tags, so you might want to define your own instead of overriding such a primitive onePepito
B
1

Since you're not always going to be using a span element and probably don't want to create a new directive for every element type, a more general workaround would be to decorate the ngClick directive to prevent the event from reaching the real ngClick's internal event handler when the event is fired on a disabled element.

var yourAppModule = angular.module('myApp');
// ...
yourAppModule.config(['$provide', function($provide) {
    $provide.decorator('ngClickDirective', ['$delegate', '$window', function($delegate, $window) {
        var isEdge = /windows.+edge\//i.test($window.navigator.userAgent);

        if (isEdge) {
            var directiveConfig = $delegate[0];
            var originalCompileFn = directiveConfig.compile;

            directiveConfig.compile = function() {
                var origLinkFn = originalCompileFn.apply(directiveConfig, arguments);

                // Register a click event handler that will execute before the one the original link
                // function registers so we can stop the event.
                return function linkFn(scope, element) {
                    element.on('click', function(event) {
                        if (event.currentTarget && event.currentTarget.disabled) {
                            event.preventDefault();
                            event.stopPropagation();
                            event.stopImmediatePropagation();
                        }
                    });

                    return origLinkFn.apply(null, arguments);
                };
            };
        }

        return $delegate;
    }]);
}]);
Bore answered 4/12, 2015 at 18:17 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.