Skip to content

Instantly share code, notes, and snippets.

@KBeDevel
Last active September 2, 2020 20:47
Show Gist options
  • Save KBeDevel/aaeb0f89b37d73d5f9d6f24fc4bbe860 to your computer and use it in GitHub Desktop.
Save KBeDevel/aaeb0f89b37d73d5f9d6f24fc4bbe860 to your computer and use it in GitHub Desktop.
Angular password visivility toggle directive
// This directive consider the use of Bootstrap 4 + Font Awesome 5
import { Directive, ElementRef, NgModule } from '@angular/core';
@Directive({
selector: '[appPasswordVisibilityToggler]' // <- Use this as an attribute in the targeted password input
})
export class PasswordInputViewDirective {
private shown = false;
private readonly buttonHide: HTMLButtonElement = document.createElement('button');
private readonly buttonShow: HTMLButtonElement = document.createElement('button');
constructor(
private readonly elementRef: ElementRef
) {
this.setup(); // Initialize default configuration
// Config "to hide" button
this.buttonHide.classList.add('btn');
this.buttonHide.classList.add('btn-outline-secondary');
this.buttonHide.setAttribute('type', 'button');
this.buttonHide.setAttribute('role', 'button');
this.buttonHide.setAttribute('title', 'Hide password');
this.buttonHide.innerHTML = '<i class="fas fa-eye-slash"></i>'; // Inject font awesome icon
// Config "to show" button
this.buttonShow.classList.add('btn');
this.buttonShow.classList.add('btn-outline-secondary');
this.buttonShow.setAttribute('type', 'button');
this.buttonShow.setAttribute('role', 'button');
this.buttonShow.setAttribute('title', 'Show password');
this.buttonShow.innerHTML = '<i class="fas fa-eye"></i>'; // Inject font awesome icon
}
public toggle(togglerDiv: HTMLElement): void {
this.shown = !this.shown;
if (this.shown) {
this.elementRef.nativeElement.setAttribute('type', 'text');
togglerDiv.removeChild(this.buttonShow);
togglerDiv.appendChild(this.buttonHide);
} else {
this.elementRef.nativeElement.setAttribute('type', 'password');
togglerDiv.removeChild(this.buttonHide);
togglerDiv.appendChild(this.buttonShow);
}
}
public setup(): void {
const parent = this.elementRef.nativeElement.parentNode;
const togglerDiv = document.createElement('div');
togglerDiv.classList.add('input-group-append');
togglerDiv.appendChild(this.buttonShow);
togglerDiv.addEventListener('click', (event) => {
if (event.isTrusted) { // Additional user agent validation
this.toggle(togglerDiv);
}
});
parent.appendChild(togglerDiv);
}
}
// The following code is used to export a directive-specific module to its use through the project
@NgModule({
declarations: [ PasswordInputViewDirective ],
exports: [ PasswordInputViewDirective ]
})
export class PasswordInputViewDirectiveModule {}
@KBeDevel
Copy link
Author

KBeDevel commented Sep 2, 2020

Consider the use of a div element with the bootstrap class input-group as the parent node of your password input field.

Example:

<div class="input-group">
  <input class="form-control" type="password" id="password" placeholder="Type a password" appPasswordVisibilityToggler>
</div>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment