javascript - How can I create a directive that adds ng-class and ng-disabled on the target element based on a condition? -


i have following code:

app.directive "ngdisableonvar", ($compile) ->   restrict: "a"   terminal: true   priority: 1000   replace:false   scope: {}   compile: compile = (element, attrs) ->     cattr = attrs["ngdisableonvar"]     element.attr("ng-class", "{'disabled': !#{cattr}}")     element.attr("ng-disabled", "!#{cattr}")     element.removeattr("ng-disable-on-var")     pre: prelink = (scope, ielement, iattrs, controller) ->      post: postlink = (scope, ielement, iattrs, controller) ->       $compile(ielement)(scope) 

i tried base code on answer given here. basically, i'd have following:

<input ngdisableonvar="somescopevariable> 

and have replaced following:

<input ng-class="{'disabled': !somescopevariable}" ng-disabled="!somescopevariable"> 

something wrong, cause though have them applied element, they're disabled, though scope variable evaluates true. doing wrong?

edit: created plunker, first 2 buttons created ng-class , ng-disabled, , other 2 buttons, should have same things applied on them through use of directive.

here plunker version shared scope: http://plnkr.co/edit/tebcql20ubh5agj6nmil?p=preview

and here's 1 without shared scope:http://plnkr.co/edit/cpm55mrha8z6bx4gbxon?p=preview

the problem is, 1 without shared scope not update. how can make them update, , have conditions depend on variables passed arguments?

edit #2: i'm starting believe scope sharing correct way these 2 buttons should act, short of creating new directive encapsulates both buttons within it. not 100% sure though.

i go edit #2 because they related. if create them separate elements, need somehow pass related element each 1 => when click on 1 button, update , related element.

here modified first approach make work: http://plnkr.co/edit/kgyilatiw9xztezt9jv1?p=preview

in example, have pass related element each directive when click can update , related element:

related-element="btnforward" 

i did modifications in directive:

scope: {       reacton: "=", //use property binding instead of function binding       relatedelement:"@"      }, link: function(scope, element, attrs) {        scope.toggle = function(){         scope.reacton = !scope.reacton;//toggle current element         var relatedscope = $("#"+scope.relatedelement).scope();//get related element's scope , toggle         relatedscope.reacton = !relatedscope.reacton;       }       //var cattr = attrs.ngdisablereacton;       element.attr("ng-class", "{'disabled': !reacton}"); //use reacton instead property of current scope       element.attr("ng-disabled", "!reacton");       element.attr("ng-click", "toggle()");        element.removeattr("ng-disable-react-on");       $compile(element)(scope);     } 

we don't need make things complex. create normal directive wrap 2 buttons.

myapp.directive("ngdisablereacton", function($compile) {   return {     restrict: "a",     templateurl:"ngdisablereacton.html",     scope: {       can_go_back: "@"     },     link: function(scope, element, attrs) {        scope.goback = function(){           scope.can_go_back = false;       }        scope.gofwd = function(){           scope.can_go_back = true;       }     }   } }); 

template:

<input type="button" value="go back" ng-click="goback()"  ng-class="{'disabled': !can_go_back}" ng-disabled="!can_go_back"> <input type="button" value="go fwd"  ng-click="gofwd()"   ng-class="{'disabled': can_go_back}" ng-disabled="can_go_back"> 

demo

another solution create parent directive container. solution most. approach, can freely change inner content of directive adding more buttons, more text,....(don't need hardcode template) parent directive works manager ensure there 1 active child @ time:

myapp.directive("ngdisablereactoncontainer", function() { //container directive manage child directives   return {     restrict: 'ea',     replace: true,     transclude: true,//use transclusion move inner content template     template: '<div ng-transclude></div>',     controller: function() {       var children = [];        this.selectchild = function(activechild) { //ensure 1 child active @ time         activechild.active = true;         angular.foreach(children, function(child) {           if (child != activechild) {             child.active = false;           }         });       }        this.addchild = function(child) {         children.push(child);       }     }   }; });  myapp.directive("ngdisablereacton", function($compile) {   return {     restrict: "a",      scope:{       active:"@"     },      require: '^?ngdisablereactoncontainer',     link: function(scope, element, attrs, controller) {        scope.active = scope.active === 'true';        controller.addchild(scope);//register container        scope.select = function(){//when element clicked, inform container toggle children accordingly.          controller.selectchild(scope);       }        //add ng-class , ng-disabled based on requirement.       element.attr("ng-class", "{'disabled': active}"); //use active instead property of current scope       element.attr("ng-disabled", "active");       element.attr("ng-click", "select()");        element.removeattr("ng-disable-react-on");       $compile(element)(scope);     }   } }); 

using these directives simple:

<div ng-disable-react-on-container>     <input ng-disable-react-on type="button" value="button 1" active="true" >     <input ng-disable-react-on type="button" value="button 2" >     <input ng-disable-react-on type="button" value="button 3" > </div> 

demo


Comments

Popular posts from this blog

php - regexp cyrillic filename not matches -

c# - OpenXML hanging while writing elements -

sql - Select Query has unexpected multiple records (MS Access) -