How to Make a Show Password Link with JQuery

While we all agree a good security measure is hiding passwords in form inputs, giving a user the ability to unhide the password is a nice usability feature. How often are you changing your password with nefarious people standing over your shoulder, right?

Really, the difference between markup for a text field and password field is just the type attribute of either 'text' or 'password'. JQuery makes it easy to work with attributes, by the $().attr() method. So, this would seemingly be a very simple task, right? Let's try it:

view plain print about
1<script type="text/javascript>
2 oldBox.attr('
type', 'text');
Whoa, this promptly results in the following error:

uncaught exception: type property can't be changed

Ouch. That didn't work like we expected, did it? Let's look at why. Once an element is inside the DOM, the type of the element can't be changed. The differences between the various DOM controls just mean we can't change a type of an element once it has been added. We can, however, clone the element, change the type then attach it to the DOM and it will work perfectly.

Give the feature a try here:

view plain print about
1<label for="CurrentPasswordInput">
2 Current password
3 <input type="password" id="CurrentPasswordInput" name="CurrentPasswordInput" value="" size="20"/>
5<label for="NewPasswordInput">
6 New password
7 <input type="password" id="NewPasswordInput" name="NewPasswordInput" value="" size="20"/>
9<label for="ConfirmNewPasswordInput">
10 New password again
11 <input type="password" id="ConfirmNewPasswordInput" name="ConfirmNewPasswordInput" value="" size="20"/>
14 <a href="" id="PasswordFieldUnhider">click to show password</a>

click to show password

The JQuery code that makes it work:

view plain print about
1<script type="text/javascript">
2    var passwordInputs = ['#CurrentPasswordInput','#NewPasswordInput','#ConfirmNewPasswordInput'];
3    var hiderLink = $('#PasswordFieldUnhider');
4    var linkTextConfig = {'password':'click to show password', 'text':'click to hide password'};
6    hiderLink.bind("click", function(){
7        var currentState = '';
8        $(passwordInputs).each( function(i, val){
10        var oldBox = $(val);
11         var newBox = oldBox.clone();
12         newBox.attr("type", ( oldBox.attr('type')=='password'?'text':'password' ) );
13         newBox.insertBefore(oldBox);
14         oldBox.remove();
15            currentState = newBox.attr('type');            
16        })
18        hiderLink.text( linkTextConfig[currentState]);
19        return false;
20    });

Here are the important parts of the script:

  1. oldBox.clone() - replicates the DOM element we want to change. We can then change the type attribute of newBox all we want to because the cloned one isn't attached to the DOM
  2. newBox.attr("type", ( oldBox.attr('type')=='password'?'text':'password' ) ) - toggles between the types of password and text. (Don't let your eyes bleed, this is a simple ternary operation...)
  3. newBox.insertBefore(oldBox) injects the newBox element (with our new fancy type) into the DOM.
  4. oldBox.remove() - removes the oldBox.
So, while we can't change certain parts of DOM elements directly, by using clone, we can pretty much do whatever we want to. Happy JQuerying!

There are no comments for this entry.

Add Comment Subscribe to Comments

12/4/09 8:21 AM # Posted By Tony Nelson

I ran into this same thing a couple weeks ago.

&lt;script type="text/javascript"&gt;
   showPassword = function() {      
      document.getElementById('password').type = document.getElementById('password').type == 'password' ? 'text' : 'password';      

&lt;input type="password" id="password" value="this-is-my-password" /&gt;

&lt;button onclick="showPassword();"&gt;Toggle Password&lt;/button&gt;

This works in Firefox (and without the need for jQuery), but not in IE. I ended up having to render a secondary field similar to how you're doing it.

12/4/09 8:32 AM # Posted By John Hodorowicz

If you need to view your password and you're on a site that doesn't offer this option you can use the Web Dev Toolbar in FF: Forms -> Show Passwords

12/4/09 5:57 PM # Posted By James Moberg

I found this while looking for an easy plug-and-play solution: