Toggle Password Field Text Visibility with jQuery

December 3, 2012

Let’s face it, we only type a password correctly about 50% of the time. And when you hit that wrong letter, you erase the entire password and start over. If you’re a fan of XKCD’s method for creating secure passwords, that’s a lot of letters to erase to start over!

So why not make the password visible by default? When’s the last time someone was creeping over your shoulder to see your password? What if we create an option to hide the letters still if someone is nearby? Let’s do that with some simple jQuery!

Demo The Final CSS and jQuery Code

The HTML Login Form

Login forms are simple. Username, password, and submit button. The code below is what you’re most likely to have, or what any content management will provide.

HTML


<form>
    <label for="username">Username: </label>
    <input id="username" name="username" type="text" placeholder="Username" />
    <label for="password">Password: </label>
    <input id="password" name="password" type="password" placeholder="Password" />

    <input id="submit" name="submit" type="submit" value="Login" />

</form>

Note that, to make this solution reliable even when JavaScript is turned off, we have chosen to set the default input type to password. We’ll use this field with JavaScript to create a dummy text field and add a button that toggles hidden/visible fields.

The jQuery

We’ll build up the jQuery in pieces. At the very end, we’ll post the final jQuery code.

Form Setup: Adding a Dummy Text Field

For security reasons, a password field cannot simply be changed to a text field once loaded in the DOM. To achieve the desired effect, we’ll be adding a dummy text field and making sure that all text typed into it is populated into the real password field, which we’ll hide off-screen.

Here is a quick CSS class and its attributes. We’ll add this class to the password field and toggle it on/off to switch between our original password field and dummy text field.

CSS


.offPage {
  position: absolute;
  bottom: 100%;
  right: 100%;
}

Now lets create the dummy text field, hide the original password field using our new class, and add the toggle link to the form.

jQuery


// ----- Setup: Add dummy text field for password and add toggle link to form; "offPage" class moves element off-screen
$('input[type=password]').each(function(){
  var el = $(this), elPH = el.attr("placeholder");
  el.addClass("offPage").before('<input class="passText" placeholder="' + elPH + '" type="text" />');
});
$('form').append('<small><a class="togglePassText" href="#">Toggle Password Visibility</a></small>');

Keeping the Fields in Sync

For the form to properly submit, we still need the original password field to contain the same text as our dummy field. Let’s make sure that what is typed in one, populated the other.

jQuery


// ----- keep password field and dummy text field in sync
$('input[type=password]').keyup(function(){
  var elText = $(this).val();
  $('.passText').val(elText);
});
$('.passText').keyup(function(){
  var elText = $(this).val();
  $('input[type=password]').val(elText);
});

Adding Functionality to Our Toggle Link/Button

To complete the effect, we need our link to remove the “offPage” class from whichever field it is set on and add it to the other field. We can set this up easily by toggling the class on/off both fields.

jQuery


// ----- Toggle link functionality - turn on/off "offPage" class on fields
$('a.togglePassText').click(function(e){
  $('input[type=password], .passText').toggleClass("offPage");
  e.preventDefault(); // <-- prevent any default actions
});

That’s all there is to it! See the final output below of all our CSS and jQuery. It looks like a lot above, but it’s really not that much.

The Final CSS and jQuery Code

Here is the final CSS and jQuery code for this process. Make sure you replace the form and field elements with your own.

CSS


.offPage {
  position: absolute;
  bottom: 100%;
  right: 100%;
}

A little bit of CSS simply hides the original password field off the page (or the text field when toggled).

The jQuery adds a dummy text field, hides the original password field, and makes sure that text typed in one is populated to the other. I’ve added comments in the code for clarity.

jQuery


// ----- Setup: Add dummy text field for password and add toggle link to form; "offPage" class moves element off-screen
$('input[type=password]').each(function(){
  var el = $(this), elPH = el.attr("placeholder");
  el.addClass("offPage").after('<input class="passText" placeholder="' + elPH + '" type="text" />');
});
$('form').append('<small><a class="togglePassText" href="#">Toggle Password Visibility</a></small>');

// ----- keep password field and dummy text field in sync
$('input[type=password]').keyup(function(){
  var elText = $(this).val();
  $('.passText').val(elText);
});
$('.passText').keyup(function(){
  var elText = $(this).val();
  $('input[type=password]').val(elText);
});

// ----- Toggle link functionality - turn on/off "offPage" class on fields
$('a.togglePassText').click(function(e){
  $('input[type=password], .passText').toggleClass("offPage");
  e.preventDefault(); // <-- prevent any default actions
});