Hi, I’m trying to implement a show/hide password similar to this one .
The problem I’m facing is that the TextInput directive from angular 2 has it’s type set method private so I can’t change the input type dynamically.
<show-hide-container>
<ion-input type="password" placeholder="Password"></ion-input>
</show-hide-container>
export class ShowHideContainer
{
show = false;
@ContentChild(TextInput) ion_input: TextInput;
constructor(){}
toggleShow()
{
this.show = !this.show;
if (this.show){
// type is private!!!
this.ion_input.type("text");
}
else {
this.ion_input.type("password");
}
}
}
any help would be much appreciated!
1 Like
Hi!
Change your directive [show-hide-input] like this:
import { Directive, HostBinding, ElementRef } from '@angular/core';
@Directive({
selector: '[show-hide-input]'
})
export class ShowHideInput {
@HostBinding() type: string;
constructor(private el: ElementRef) {
this.type = 'password';
}
changeType(type: string) { // in your case function name is type
this.type = type;
this.el.nativeElement.children[0].type = this.type; // change type for input inside the ion-input
}
}
And in your template:
<show-hide-container>
<ion-input type="password" placeholder="Password" show-hide-input></ion-input> // add the directive show-hide-input
</show-hide-container>
It works for me.
1 Like
Thank you so much!
At first I thought I could avoid using another directive (show-hide-input
) and use the <ion-input>
instead. But the methods I needed to access were private within the <ion-input>
component, so it seems there’s no choice but to use the show-hide-input
directive for this.
Another issue i found is that if you are using <ion-item>
component along with <ion-input>
you should put both of them inside the <show-hide-container>
THIS DOESN’T WORK
<ion-item>
<show-hide-container>
<ion-input type="password" placeholder="Password" formControlName="password" show-hide-input></ion-input>
</show-hide-container>
</ion-item>
THIS WORKS
<show-hide-container>
<ion-item>
<ion-input type="password" placeholder="Password" formControlName="password" show-hide-input></ion-input>
</ion-item>
</show-hide-container>
Having said that, it would be awesome if the guys from the ionic team could write a post or guide about the proper way to extend and create custom directives for the ionic framework. I believe there are tons of developers like me that want to crete awesome stuff with ionic and at the end these custom directives and UI/UX widgets will be super useful for the community.
The community is what makes ionic great.
1 Like
There is no need to do all that is written above, just do this
in .html
<ion-item>
<ion-label fixed>Password</ion-label>
<ion-input #input type="password" [(ngModel)]="loginUtente.password"></ion-input>
</ion-item>
<ion-item>
<ion-label for="checkbox" *ngIf="!passwordCheckbox">show password</ion-label>
<ion-label for="checkbox" *ngIf="passwordCheckbox">hide password</ion-label>
<ion-checkbox class="marginTop" id="checkbox" style="border-style: none;" [(ngModel)]="passwordCheckbox" (click)="showPassword(input)"></ion-checkbox>
</ion-item>
in .ts
showPassword(input: any): any {
input.type = input.type === 'password' ? 'text' : 'password';
}
I hope to have helped
3 Likes
I would much prefer binding [type]
instead of directly fooling with DOM attributes in showPassword()
(which should rather be named toggleShowPassword()
or something to indicate that it doesn’t just show the password).
Using the approach of the OP’s accepted solution in the latest Ionic 2 version I get the following error:
Unhandled Promise rejection: Template parse errors:
Can’t bind to ‘type’ since it isn’t a known property of ‘ion-input’.
…
I created two separate .ts files for both the container and input attribute directive & imported them into the declarations of app.module.ts
.
Does anyone know to resolve this? Thanks!
Hi thorgalle, this is another simple solution. I hope helped.
login.html
<ion-item>
<ion-input [type]="getType()"></ion-input>
<ion-icon name="eye" item-right (click)="toggleTextPassword()"></ion-icon>
</ion-item>
login.ts
export class LoginPage {
isActiveToggleTextPassword: Boolean = true;
public toggleTextPassword(): void{
this.isActiveToggleTextPassword = (this.isActiveToggleTextPassword==true)?false:true;
}
public getType() {
return this.isActiveToggleTextPassword ? 'password' : 'text';
}
}
6 Likes
I don’t know why this would be better then this:
HTML
<ion-input [type]="password_type" placeholder="Password" name="password" [(ngModel)]="password" required></ion-input>
<ion-icon name="eye" item-right (click)="togglePasswordMode()"></ion-icon>
TS
password_type: string = 'password';
togglePasswordMode() {
this.password_type = this.password_type === 'text' ? 'password' : 'text';
}
10 Likes
I am also getting this issue. I thought it was related to lazy loading but maybe it is the ionic version?
1 Like
jaydz
April 1, 2018, 8:02pm
10
This was a easy, 100% effective solution.
minor change on my end
togglePasswordMode() {
this.password_type === 'text' ? 'password' : 'text';
}
Not sure why you had the extra this.password_type =
Typo or just a personal preference for doing things?
2 Likes
jaydz
April 1, 2018, 8:21pm
12
No problem. Thanks for the pragmatic solution
1 Like
Hey! I am getting errors with this. Error: Template parse errors: Can't bind to 'type' since it isn't a known property of 'ion-input'.
I recently updated to Ionic4. Is that the reason? Any update
Sorry I figured it out… Change the @HostBinding to @Input
Simple and neat solution. Thank you
alaswer
January 10, 2020, 9:23pm
18
simple, not complicated and effective solution… thank you!
pa7ry
January 31, 2020, 12:15pm
19
HTML
<ion-label position="floating">Password</ion-label>
<ion-input [type]="hide ? 'password' : 'text'" required></ion-input>
<ion-icon slot="end" [name]="hide ? 'eye' : 'eye-off'" (click)="hide = !hide"></ion-icon>
TS
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-login-form',
templateUrl: './login-form.component.html',
styleUrls: ['./login-form.component.scss'],
})
export class LoginFormComponent implements OnInit {
hide = true;
constructor() { }
ngOnInit() {}
}
I think that the easiest way to change the value of the attributes is with an if and a boolean , by clicking on the eye icon, for example
3 Likes
Thanks! This was so clean and easy to implement
simple, short and clean solution
simple, short and clean solution