miguelslp - Vanilla JS

Toggling passwords in multiple forms

Change Username

Enter your username and password to change your username.

Change Password

Enter your current password and new password below.

<h2>Change Username</h2>

<p>Enter your username and password to change your username.</p>

<form>
<div>
<label for="username">Username</label>
<input type="text" name="username" id="username">
</div>

<div>
<label for="password">Password</label>
<input type="password" name="password" id="password" data-target="changeUsername">
</div>

<div>
<label for="show-password">
<input type="checkbox" name="show-passwords" id="show-password" data-passwordToggle="changeUsername">
Show password
</label>
</div>

<p>
<button type="submit">Change Username</button>
</p>
</form>

<h2>Change Password</h2>

<p>Enter your current password and new password below.</p>

<form>
<div>
<label for="current-password">Current Password</label>
<input type="password" name="current-password" id="current-password" data-target="changePassword">
</div>

<div>
<label for="new-password">New Password</label>
<input type="password" name="new-password" id="new-password" data-target="changePassword">
</div>

<div>
<label for="show-passwords">
<input type="checkbox" name="show-passwords" id="show-passwords" data-passwordToggle="changePassword">
Show passwords
</label>
</div>

<p>
<button type="submit">Change Passwords</button>
</p>
</form>
<script async>

// Variables
var passwords = Array.from(document.querySelectorAll('[type="password"]'));

// Methods
var togglePasswords = function (event) {
if (!event.target.matches('[data-passwordToggle]')) return;
var targets = event.target.getAttribute('data-passwordToggle');
passwords.forEach(element => {
if (element.matches(`[data-target="${targets}"]`)) {
element.type = event.target.checked ? 'text' : 'password';
};
})
};

// Listeners
document.addEventListener('click', togglePasswords);

</script>

Other ideas

  • Making the selection with a data attribute only on the password inputs and querying the parent form. The form querying could also be done with the form property.
    var otherAlternative = function (event) {
      if (event.target.matches('[name="show-passwords"]')) {
        let formPasswords = Array.from(event.target.closest('form').querySelectorAll('[data-password]'));
        formPasswords.forEach(element => {
          element.type = event.target.checked ? 'text' : 'password';
        });
      };
    };