While working on my new app theme for Ionic framework 2, based on Angular 2, I needed a show-hide component for a password input field.
It’s basically an input field with a button that will change the type of the input from password to text and back.
Something like this.
You could do this by creating your own component:
import {Component} from '@angular/core' @Component({ selector: 'show-hide-input', template: '<input type="{{type}}" /><a (click)="toggleShow()">show/hide</a>' }) export class ShowHideInput { type= "password"; show = false; constructor(){ } toggleShow() { this.show = !this.show; if (this.show){ this.type = "text"; } else { this.type = "password"; } } }
But what if you want to add some extra functionality to the input, for example bind it to a model using ngModel?
Unfortunately this isn’t working:
<show-hide-input [ngModel]="password"></show-hide-input>
So what we need to do is creating a container for the input and use transclusion (ng-content) in the component to copy the content of the container.
import {Component} from '@angular/core' @Component({ selector: 'show-hide-container', template: `<ng-content></ng-content> <a (click)="toggleShow()">show/hide</a>` }) export class ShowHideContainer { show = false; constructor(){} toggleShow() { this.show = !this.show; if (this.show){ //change the type to text } else { //change the type to password } } }
This way we keep the functionality of the input element, but how do we get to the input to change the type?
We can solve this by using the ContentChild decorator in our component and adding a reference on the input within the container by adding #showhideinput to the input.
So our main component will look something like this:
import {Component} from '@angular/core' @Component({ selector: 'show-hide-app', template: ` <h1>Show/Hide Password</h1> <label>Password:</label> <show-hide-container> <input type="password" #showhideinput [ngModel]="password" /> </show-hide-container>` }) export class AppComponent { password = "secret"; }
And the container component will look like this
import {Component, ContentChild } from '@angular/core' @Component({ selector: 'show-hide-container', template: `<ng-content></ng-content> <a (click)="toggleShow()">show/hide</a>` }) export class ShowHideContainer { show = false; @ContentChild('showhideinput') input; constructor(){} toggleShow() { this.show = !this.show; console.log(this.input); if (this.show){ this.input.nativeElement.type='text'; } else { this.input.nativeElement.type='password'; } } }
Of course you can make things fancy by adding some nice icons, but I leave that up to you.
Source code is available here.
Or you can see it in action here.
And please checkout my customizable Ionic theme.
8 comments. Leave new
Can we use directive to achieve this?
What do you exactly mean? I am using a directive in the solution…
Try this: https://www.npmjs.com/package/ngx-show-hide-password
Great! Thanks…
Nice. It helped me. Thanks buddy!
Nice. It really works. Thanks.
nice
take a look at the `mat-pass-toggle-visibility` component of the @angular-material-extensions/password-strength library https://github.com/angular-material-extensions/password-strength