7

We can use data-binding on input elements like this:

<input type="{{ showPassword ? 'text' : 'password' }}" name="password">

But this has similar problems as using data-binding on a href attribute (see ngHref). This way there is an input element in the dom with the type {{ showPassword ? 'text' : 'password' }} until angular loads. It looks convenient to have an ngType directive much like ngHref, what could be used this way:

<input type="password" ng-type="{{ showPassword ? 'text' : 'password' }}" name="password">

Is there any other way to do it? Do I have to implement this ngType thing?

3
  • Do you have to use it with standard <input>? A directive wrapping the two variant of the input is doable. Commented Aug 31, 2016 at 11:10
  • @NikosParaskevopoulos I wonder if ng-model will work on that too Commented Aug 31, 2016 at 11:37
  • Yes, certainly. It needs a custom control to use ng-model on the outer directive, see here for how. Commented Aug 31, 2016 at 13:45

1 Answer 1

10

Custom directive that changes the <input> type:

To show or hide the password use a custom directive:

app.directive("showPassword", function() { 
    return function linkFn(scope, elem, attrs) {
        scope.$watch(attrs.showPassword, function(newValue) {
            if (newValue) {
                elem.attr("type", "text");
            } else {
                elem.attr("type", "password");
            };
        });
    };
});

Usage

 <input type=password show-password="showPassword" 
        ng-model="thePassword">

The show-password directive watches the defined scope variable and changes the input to type=text when truthy and back to type=password when falsey.

The DEMO

angular.module("myApp",[])
.directive("showPassword", function() { 
    return function linkFn(scope, elem, attrs) {
        scope.$watch(attrs.showPassword, function(newValue) {
            if (newValue) {
                elem.attr("type", "text");
            } else {
                elem.attr("type", "password");
            };
        });
    };
})
<script src="//unpkg.com/angular/angular.js"></script>
<div ng-app='myApp'>

    <button ng-click="showPassword = true">Show Password</button><br>
    <button ng-click="showPassword = false">Hide Password</button><br>
    
    <input type=password show-password="showPassword" 
           ng-model="thePassword">
    <hr>
    PASSWORD == {{thePassword}}
</div>

Sign up to request clarification or add additional context in comments.

1 Comment

This seems to be the easiest solution that does not involve manipulating dom from the controller. I like the idea of not using ng-type but a show-password so it is impossible to set it to date or number accidentally from the controller.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.