Creating a toggle password plugin with vanilla JavaScript
Yesterday, we looked at how to toggle password visibility with vanilla JS. Today, we’re going to convert our script into a plugin that you can reuse across pages and sites.
Our Script
If you didn’t read yesterday’s article, here’s the markup for our form.
<label for="username">Username</label>
<input type="text" name="username" id="username">
<label for="password">Password</label>
<input type="password" name="password" id="password">
<label for="show_password">
<input type="checkbox" name="show_password" id="show_password">
Show Password
</label>And here’s our final script.
// Listen for click events
document.addEventListener('click', function (event) {
// If the clicked element isn't our show password checkbox, bail
if (event.target.id !== 'show_password') return;
// Get the password field
var password = document.querySelector('#password');
if (!password) return;
// Check if the password should be shown or hidden
if (event.target.checked) {
// Show the password
password.type = 'text';
} else {
// Hide the password
password.type = 'password';
}
}, false);
Abstracting our selectors
The challenge with the script we wrote yesterday is that it requires specific selectors—#show_password and #password—to work.
Ideally, we’d like to use this on different forms that may not use the same field IDs. We might also want to show the contents of multiple password fields in a single form (for example, a change password form that asks you to confirm your new password).
To do that, we need to use a more abstract selector for our checkbox, and dynamically get the password field(s) that we want to show or hide.
The Markup
To achieve this, we’ll use a data attribute, [data-show-password], and use the selector for our password field(s) as it’s value.
<label for="password">Password</label>
<input type="password" name="password" id="password">
<label for="show_password">
<input type="checkbox" name="show_password" id="show_password" data-show-password="#password">
Show Password
</label>The JavaScript
In our JavaScript file, we’ll change our event listener to check for the [data-show-password] attribute using the hasAttribute() method.
// Listen for click events
document.addEventListener('click', function (event) {
// If the clicked element isn't our show password checkbox, bail
if (!event.target.hasAttribute('data-show-password')) return;
// ...
}, false);
If it’s our checkbox, we’ll use the attribute value (via the getAttribute() method) to get our password field.
// Listen for click events
document.addEventListener('click', function (event) {
// If the clicked element isn't our show password checkbox, bail
if (!event.target.hasAttribute('data-show-password')) return;
// Get the password field
var password = document.querySelector(event.target.getAttribute('data-show-password'));
if (!password) return;
// Check if the password should be shown or hidden
if (event.target.checked) {
// Show the password
password.type = 'text';
} else {
// Hide the password
password.type = 'password';
}
}, false);
Toggling multiple password fields
To toggle multiple password fields, we need to make just a few small tweaks.
First, we’ll use querySelectorAll() to get all all matching selectors instead of just one.
// Listen for click events
document.addEventListener('click', function (event) {
// If the clicked element isn't our show password checkbox, bail
if (!event.target.hasAttribute('data-show-password')) return;
// Get the password field
var password = document.querySelectorAll(event.target.getAttribute('data-show-password'));
if (password.length < 1) return;
// ...
}, false);
Next, we need to loop through each result instead of just running our code.
// Listen for click events
document.addEventListener('click', function (event) {
// If the clicked element isn't our show password checkbox, bail
if (!event.target.hasAttribute('data-show-password')) return;
// Get the password field
var password = document.querySelectorAll(event.target.getAttribute('data-show-password'));
if (password.length < 1) return;
// Loop through each field
for (var i = 0; i < password.length; i++) {
// Check if the password should be shown or hidden
if (event.target.checked) {
// Show the password
password[i].type = 'text';
} else {
// Hide the password
password[i].type = 'password';
}
}
}, false);
Now, we can toggle multiple password fields in a form by adding a more generic selector for our password fields (for example, a .passwords class).
<label for="password">Password</label>
<input type="password" name="password" id="password" class="password">
<label for="confirm_password">Confirm Password</label>
<input type="password" name="confirm_password" id="confirm_password" class="password">
<label for="show_password">
<input type="checkbox" name="show_password" id="show_password" data-show-password=".password">
Show Password
</label>