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>