Skip to content

Instantly share code, notes, and snippets.

@cferdinandi
Last active November 28, 2023 21:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cferdinandi/7874a6d599fc4c085c69086978478004 to your computer and use it in GitHub Desktop.
Save cferdinandi/7874a6d599fc4c085c69086978478004 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html>
<head>
<title>Toggle Password</title>
<style type="text/css">
body {
margin: 1em auto;
max-width: 30em;
width: 88%;
}
label,
input:not([type="checkbox"]),
toggle-password {
display: block;
width: 100%;
}
input,
toggle-password {
margin-bottom: 1em;
}
toggle-password [aria-pressed="true"] [is-hidden],
toggle-password [aria-pressed="false"] [is-visible] {
display: none;
}
</style>
</head>
<body>
<h1>Toggle Password</h1>
<form>
<!-- A checkbox toggle -->
<toggle-password>
<label for="password-1">Password</label>
<input id="password-1" name="password" type="password" value="test1234">
<label hidden>
<input toggle type="checkbox">
Show password
</label>
</toggle-password>
<!-- A button toggle -->
<toggle-password>
<label for="password-2">Password</label>
<input id="password-2" name="password" type="password" value="test1234">
<button toggle hidden>
Show password
</button>
</toggle-password>
<!-- Show password fields by default -->
<toggle-password visible>
<label for="password-3">Password</label>
<input id="password-3" name="password" type="password" value="test1234">
<button toggle hidden>
<span is-hidden>Show Password</span>
<span is-visible>Hide Password</span>
</button>
</toggle-password>
</form>
<script>
customElements.define('toggle-password', class extends HTMLElement {
/**
* Instantiate the Web Component
*/
constructor () {
// Get parent class properties
super();
// Define properties
this.passwords = this.querySelectorAll('[type="password"]');
this.trigger = this.querySelector('[toggle]');
if (!this.trigger) return;
this.type = this.trigger.tagName.toLowerCase();
this.visible = this.hasAttribute('visible');
this.handler = this.createHandler();
// Setup the UI
this.init();
}
/**
* Show hidden elements and add ARIA
*/
init () {
// Show hidden toggle
let hidden = this.trigger.closest('[hidden]');
if (hidden) {
hidden.removeAttribute('hidden');
}
// If toggle is a button, add aria-pressed
if (this.type === 'button') {
this.trigger.setAttribute('aria-pressed', this.visible);
this.trigger.setAttribute('type', 'button');
}
// If passwords should be visible, show them by default
if (this.visible) {
this.show();
}
}
/**
* Show passwords
*/
show () {
for (let pw of this.passwords) {
pw.type = 'text';
}
if (this.type === 'button') {
this.trigger.setAttribute('aria-pressed', true);
}
}
/**
* Hide password visibility
*/
hide () {
for (let pw of this.passwords) {
pw.type = 'password';
}
if (this.type === 'button') {
this.trigger.setAttribute('aria-pressed', false);
}
}
/**
* Toggle password visibility on or off
*/
toggle () {
let show = this.type === 'button' ? this.trigger.getAttribute('aria-pressed') === 'false' : this.trigger.checked;
if (show) {
this.show();
} else {
this.hide();
}
}
/**
* Create the event handler
* @return {Function} The event handler function
*/
createHandler () {
return (event) => {
this.toggle();
};
}
/**
* Start listening to clicks
*/
connectedCallback () {
this.trigger.addEventListener('click', this.handler);
}
/**
* Stop listening to clicks
*/
disconnectedCallback () {
this.trigger.removeEventListener('click', this.handler);
}
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment