When manipulating the disabled attribute, the input style changes but the icons are still clickable.
I am changing the attribute value in a watcher in the link function. To clarify my statement please see this example code:
Template:
<md-input-container group="groupname" is-key="false" my-group-input>
<md-datepicker ng-model="myDate" md-placeholder="Enter date"></md-datepicker>
</md-input-container>
Link function of attribute directive
function exampleDirective($exampleFactory) {
return {
restrict: 'A',
scope: {
isKey: '=',
group: '@',
},
controller: MyGroupInputController,
link: function(scope, element, attr) {
var inputElement = element.find('md-datapicker');
scope.$watch(function () {
return $exampleFactory.InputItems;
}, function (newval, oldval) {
if (newval[attr.group].isEmpty === true) {
inputElement.attr('disabled', 'disabled');
// inputElement.attr('ng-disabled', 'true'); doesn't work
} else {
inputElement.removeAttr('disabled');
//inputElement.attr('ng-disabled', false);
}
}, true);
}
}
}
Expected behavior is:

Actual behavior is:

Setting inputElement.attr('ng-disabled', 'true'); seems to work when I inspect the page:

But doesn't affect the md-datepicker
How wil I be able to change the ng-disabled of the md-datepicker?
@topherfangio - let's make sure we are consistent with the way other components use disabled, ng-disabled, etc.
@Dennisoost ng-disabled should work, however you should keep in mind that the linking phase (which you're using) happens after the datepicker has been set up. This means that the datepicker won't watch for the disabled attribute since it wasn't there during compilation. To work around this, you've got two options:
ng-disabled expression to your datepicker either directly in the template, or in a compile block.setDisabled method to toggle it manually. Here's how your example could be rewritten:function exampleDirective($exampleFactory) {
return {
restrict: 'A',
scope: {
isKey: '=',
group: '@',
},
controller: MyGroupInputController,
link: function(scope, element, attr) {
var datepickerCtrl = element.find('md-datapicker').controller('mdDatepicker');
scope.$watch(function() {
return $exampleFactory.InputItems;
}, function(newval) {
datepickerCtrl.setDisabled(newval[attr.group].isEmpty === true);
}, true);
}
};
}
Let me know if you have any questions.
This issue is closed as it falls in the 'deprecated' category. We deprecate issues for one or more of the following reasons:
Pull Requests are welcomed to resolve this issue. But note that not all community PRs will be merged into master. Pull Requests with large changes or large scope impacts will probably be rejected [due to stability risks to existing users].
@crisbeto I tried solution 1 before and can't seem to get it to work. Solution 2 fixed it for me! thanks! Can you point me to the documentation regarding the .controller() method and the setDisabled() method? I can't seem to find those.
So for the datepicker it is working, but for md-select it says that the 'setDisabled is not a function'.
@Dennisoost Solution 2 isn't documented, because it's a part of the internal datepicker API. .controller returns the controller of the md-datepicker directive which then lets you use the internal API directly, however that doesn't mean that other components would implement it in the same way. The recommended way of doing this is option 1, however that wasn't feasible in your particular case (adding the ng-disabled attribute in the linking phase).
@crisbeto ah ok, makes sense. I just tried solution 1 again, with adding a ng-disabled directly to the template and I also tried to add ng-disabled in the compile function, but both have the same effect. The values seem to change when I inspect the DOM, but no changes to the styling of the component.
Currently I fixed this by getting the separate elements of the md-components in the link function, and adding a disable attribute to these elements. It works, but it feels like a unclean fix.
Thanks for your help
Alright, then it sounds like a bug. I'll follow this up later.
@Dennisoost - please provide a working CodePen that demonstrates the issue; and will be used to validate any fixes.
@Dennisoost I wasn't able to reproduce it. It worked fine both when using only disabled on load and using ng-disabled to toggle it dynamically. Here's a codepen. I'll close this since it looks like everything works as expected, but we can continue the discussion.
@crisbeto I will make a codepen in one of the coming days.
@crisbeto While making a codepen I got a bit carried away and spend some time trying to fix my problem. So eventually I found that I had to compile the html element and bind it to the scope. (I think you said something like this in your first comment, wasn't clear for me since I wasn't familair with the $compile service).
See: http://codepen.io/dennisoost/pen/XjLemB
Thanks for you help, this issue is closed for me.
Yes, if you're adding the ng-disabled expression at a later point, you need to recompile your element. Note that what you're doing in your codepen is a bad way of using $compile since you're recompiling the element for every time your expression changes. Instead you should only do it once when the link function runs.
@crisbeto
http://codepen.io/dennisoost/pen/rMEQpa
I think this is what you mean? But this doesn't work for me.
Here's what I mean @Dennisoost: http://codepen.io/crisbeto/pen/rMEgBJ?editors=0010
Or if you want it even better, you can do this. This avoids having to deal with $compile directly: http://codepen.io/crisbeto/pen/QKXRwd?editors=0010
@crisbeto
Yes, eventually I found out. This works great for almost all input elements except md-select
see: http://codepen.io/dennisoost/pen/qazGag

Yeah, md-select is pretty complicated and I'm not too familiar with the way it's set up.
@crisbeto
Your second codepen works (also on the md-select!), it isn't clear for me why though. To me it seems like the set of the attribute is dependent on something you add later in the postLink.
Anyway thanks for your patience and your help.
@crisbeto still stuck on one small thing. When using a scope in a directive the factoryRef is somehow not set. See: http://codepen.io/dennisoost/pen/Wovdyy
Edit: I fixed this by removing the:
scope: {
iskey: '='
}
And by getting the attribute values like this:
compile: function(tElement, tAttrs){
var myAttr = tAttrs.iskey
...
}
Most helpful comment
Here's what I mean @Dennisoost: http://codepen.io/crisbeto/pen/rMEgBJ?editors=0010
Or if you want it even better, you can do this. This avoids having to deal with
$compiledirectly: http://codepen.io/crisbeto/pen/QKXRwd?editors=0010