Angular’s ngClicks can be attached to anything. This makes it easy to add interactivity to elements on the DOM. Your program might require that these click callbacks be disabled at certain points, such as during form processing. ngClick doesn’t have a toggle built in. Let’s build one that might help.
In our app we’re going to track the state of the UI via various events that get passed in scope. We slap our directive as an attribute on an element and it will respond by disabling or enabling on certain events. Here’s the directive:
angular.module('app.directives').directive 'disableToggle', -> restrict: 'A' replace: false link: (scope, element, attrs) -> defaultDisableEvt = 'click:disable' defaultEnableEvt = 'click:enable' disableEvt = attrs.disableEvt || defaultDisableEvt enableEvt = attrs.enableEvt || defaultEnableEvt disableEvts = disableEvt.split(/\ *?,\ *?/) enableEvts = enableEvt.split(/\ *?,\ *?/) for evt in disableEvts scope.$on evt, (evt) -> element.attr 'disabled', 'disabled' element.addClass 'is-disabled' scope.disabledToggled = true for evt in enableEvts scope.$on evt, (evt) -> element.removeAttr 'disabled' element.removeClass 'is-disabled' scope.disabledToggled = false
The directive allows for listening on multiple events. This is useful if your button should be disabled/enabled via multiple events. Just separate your event list with commas. If you don’t want to specify any events, the directive uses two default events, ‘click:disable’ and ‘click:enable’.
The directive sets the
disabled attribute, commonly used in form fields. It also sets the
is-disabled class so your app can style this state consistently in the UI.
Lastly, the directive also sets a
scope.disabledToggled variable on the scope of the element. This will be useful for elements which are not form elements and which do not prevent clicking just because their
disabled attribute is set to
disabled. Instead, we’ll use this value to short-circuit the
ng-click event itself.
So here it is in action on the template:
<button ng-click="disabledToggled || doClickyThings()" disable-toggle enable-evt="click:enable,photo:clear" disable-evt="photo:add">Click Me</button>
Here, we’re setting custom events for disabling and enabling the button. And note the
ng-click value. The
doClickyThings() function will not get called if
disabledToggled is true.
So, what do you think. Is there an easier way to get this kind of functionality? What could we do to make it better?