Enable / Disable Binding Using AngularJS

How to enable / disable anchor tags using a directive approach?

Example:

  • when you click on the edit link, the creation and deletion must be disabled or disabled.
  • when you click on the link to create, edit and delete, you must disable or gray out

JAVASCRIPT:

angular.module('ngApp', []).controller('ngCtrl',['$scope', function($scope){ $scope.create = function(){ console.log("inside create"); }; $scope.edit = function(){ console.log("inside edit"); }; $scope.delete = function(){ console.log("inside delete"); }; }]).directive('a', function() { return { restrict: 'E', link: function(scope, elem, attrs) { if(attrs.ngClick || attrs.href === '' || attrs.href === '#'){ elem.on('click', function(e){ e.preventDefault(); if(attrs.ngClick){ scope.$eval(attrs.ngClick); } }); } } }; }); 

LINK to CODE

+51
angularjs angularjs-directive
May 2 '14 at 9:50
source share
10 answers

Update: Disabling href works better when returning a link function. The code below is updated.

aDisabled naturally before ngClick , because directives are sorted alphabetically. When aDisabled renamed to tagDisabled , the directive does not work.




To β€œdisable” the β€œa” tag, I need the following things:

  • href links will not be executed when clicked
  • ngClick events do not fire when clicked
  • styles are changed by adding a disabled class

This directive does this by imitating the ngDisabled directive. Based on the value of the a-disabled directive, all of the above functions are switched.

 myApp.directive('aDisabled', function() { return { compile: function(tElement, tAttrs, transclude) { //Disable ngClick tAttrs["ngClick"] = "!("+tAttrs["aDisabled"]+") && ("+tAttrs["ngClick"]+")"; //return a link function return function (scope, iElement, iAttrs) { //Toggle "disabled" to class when aDisabled becomes true scope.$watch(iAttrs["aDisabled"], function(newValue) { if (newValue !== undefined) { iElement.toggleClass("disabled", newValue); } }); //Disable href on click iElement.on("click", function(e) { if (scope.$eval(iAttrs["aDisabled"])) { e.preventDefault(); } }); }; } }; }); 

Here is a CSS style that might point to a disabled tag:

 a.disabled { color: #AAAAAA; cursor: default; pointer-events: none; text-decoration: none; } 

And here is the code in action, with your example

+51
Aug 19 '14 at 19:00
source share

My problem was slightly different: I have anchor tags that define href , and I want to use ng-disabled to prevent the link from moving anywhere when clicked. The solution is to disable href when the link is disabled, for example:

 <a ng-href="{{isDisabled ? '' : '#/foo'}}" ng-disabled="isDisabled">Foo</a> 

In this case, ng-disabled is only used to style the element.

If you want to avoid using informal attributes , you will need to style it yourself:

 <style> a.disabled { color: #888; } </style> <a ng-href="{{isDisabled ? '' : '#/foo'}}" ng-class="{disabled: isDisabled}">Foo</a> 
+22
Aug 19 '15 at 1:35
source share

For people who don't want a complicated answer, I used Ng-If to solve this for something like this:

 <div style="text-align: center;"> <a ng-if="ctrl.something != null" href="#" ng-click="ctrl.anchorClicked();">I'm An Anchor</a> <span ng-if="ctrl.something == null">I'm just text</span> </div> 
+8
Dec 20 '16 at 18:03
source share

Change @Nitin answer to work with dynamic disconnect:

 angular.module('myApp').directive('a', function() { return { restrict: 'E', link: function(scope, elem, attrs) { elem.on('click', function(e) { if (attrs.disabled) { e.preventDefault(); // prevent link click } }); } }; }); 

This checks for a disabled attribute and its value each time it is clicked.

+5
Oct 10 '16 at 7:59
source share

Denial of responsibility:

The OP made this comment on another answer:

We can have ngDisabled for buttons or input tags; Using CSS, we can make the button look like an anchor tag, but that doesn't help much! I was more interested in how this can be done using a directive approach or an angular way to do this?




You can use the variable inside the area of ​​your controller to disable links / buttons according to the last button / link you clicked, with ng-click to set the variable with the correct value and ng-disabled to disable the button if necessary according with a value in a variable.

I updated your Plunker to give you an idea.

But basically, this is something like this:

  <div> <button ng-click="create()" ng-disabled="state === 'edit'">CREATE</button><br/> <button ng-click="edit()" ng-disabled="state === 'create'">EDIT</button><br/> <button href="" ng-click="delete()" ng-disabled="state === 'create' || state === 'edit'">DELETE</button> </div> 
+4
May 2 '14 at 12:28
source share

You tried to use lazy evaluation of expressions like disabled || someAction() disabled || someAction() ?

Suppose I defined something like this in the controller:

 $scope.disabled = true; 

Then I can disable the link and apply inline styles as follows:

 <a data-ng-click="disabled || (GoTo('#/employer/'))" data-ng-style="disabled && { 'background-color': 'rgba(99, 99, 99, 0.5)', }">Higher Level</a> 

Or better yet, disable the link and apply the class as follows:

 <a data-ng-click="disabled || (GoTo('#/employer/'))" data-ng-class="{ disabled: disabled }">Higher Level</a> 

Note: you will have class="disabled" applied to the DOM element by this statement.

At this point, you just need to handle what you do with GoTo() . In my case, it is as simple as redirecting to a bound state:

 $scope.GoTo = function (state) { if (state != undefined && state.length > 0) { $window.location.hash = state; } }; 

Instead of limiting ngDisabled you are limited by what you decide to do.

Using this technique, I have successfully applied permission level checking to enable or disable user access to a specific part of my module.

Simple plunker to show point

+2
Aug 11 '15 at 15:35
source share

You can create a custom directive that is somehow similar to ng-disabled and disable a specific set of elements:

  • viewing property changes of a custom directive, for example. my-disabled .
  • clone the current item without adding event handlers.
  • add css properties to the cloned element and other attributes or event handlers that will provide the disabled state of the element.
  • when changes are detected in the observed property, replace the current element with the cloned element.

HTML

  <a my-disabled="disableCreate" href="#" ng-click="disableEdit = true">CREATE</a><br/> <a my-disabled="disableEdit" href="#" ng-click="disableCreate = true">EDIT</a><br/> <a my-disabled="disableCreate || disableEdit" href="#">DELETE</a><br/> <a href="#" ng-click="disableEdit = false; disableCreate = false;">RESET</a> 

JAVASCRIPT

 directive('myDisabled', function() { return { link: function(scope, elem, attr) { var color = elem.css('color'), textDecoration = elem.css('text-decoration'), cursor = elem.css('cursor'), // double negation for non-boolean attributes eg undefined currentValue = !!scope.$eval(attr.myDisabled), current = elem[0], next = elem[0].cloneNode(true); var nextElem = angular.element(next); nextElem.on('click', function(e) { e.preventDefault(); e.stopPropagation(); }); nextElem.css('color', 'gray'); nextElem.css('text-decoration', 'line-through'); nextElem.css('cursor', 'not-allowed'); nextElem.attr('tabindex', -1); scope.$watch(attr.myDisabled, function(value) { // double negation for non-boolean attributes eg undefined value = !!value; if(currentValue != value) { currentValue = value; current.parentNode.replaceChild(next, current); var temp = current; current = next; next = temp; } }) } } }); 
+1
May 03 '14 at 1:40
source share

Make the switch function in the corresponding area a gray link .

First create the following CSS classes in your .css file.

 .disabled { pointer-events: none; cursor: default; } .enabled { pointer-events: visible; cursor: auto; } 

Add the variable $ scope.state and $ scope.toggle. Edit your controller in a JS file, for example:

  $scope.state='on'; $scope.toggle='enabled'; $scope.changeState = function () { $scope.state = $scope.state === 'on' ? 'off' : 'on'; $scope.toggleEdit(); }; $scope.toggleEdit = function () { if ($scope.state === 'on') $scope.toggle = 'enabled'; else $scope.toggle = 'disabled'; }; 

Now in HTML tags are edited as:

 <a href="#" ng-click="create()" class="{{toggle}}">CREATE</a><br/> <a href="#" ng-click="edit()" class="{{toggle}}">EDIT</a><br/> <a href="#" ng-click="delete()" class="{{toggle}}">DELETE</a> 

To avoid the problem of disconnecting the channel, change the CSS DOM class at the end of the function.

 document.getElementById("create").className = "enabled"; 
+1
Aug 26 '15 at 7:45
source share

You can override the a tag using the angular directive:

 angular.module('myApp').directive('a', function() { return { restrict: 'E', link: function(scope, elem, attrs) { if ('disabled' in attrs) { elem.on('click', function(e) { e.preventDefault(); // prevent link click }); } } }; }); 

In html:

 <a href="nextPage" disabled>Next</a> 
+1
Jan 15 '16 at 7:31
source share

I expect anchored tags to lead to a static page with a url. I think buttons are more suitable for your use case, and then you can use ngDisabled to disable it. From the docs: https://docs.angularjs.org/api/ng/directive/ngDisabled

0
May 2 '14 at 10:08
source share



All Articles