Toggling a password field between plain text and password

Posted in Javascript -

Some time back I posted how to show plain text in a password field and make it a regular password field on focus using jQuery, so that it could show some default text (i.e. "password") before anything was entered and then work like a normal password field when the user started typing text into it.

As someone a couple of days ago pointed out in the comments on that page, while it's not possible to change the type of a password input with jQuery, it is with regular Javascript. So this post shows how to do just that and which browsers do and don't support it.

Update December 10th 2015

You should really use placeholders these days instead of doing all this sort of mucking around; the only catch is there are still some people using older browsers (e.g. IE8 & IE9) which do not support placeholders. Take a look at my more up to date post which shows how to make placeholders work in older browsers.

jQuery and changing the input field type

jQuery does not allow it because IE versions prior to 9 do not allow it. If you try to run the following piece of code where myPasswordField is an input with type password, it will result in the error "Uncaught type property can't be changed":

$('#myPasswordField').attr('type', 'text');

Browser support for changing the input field type with regular Javascript

IE9 and all other browsers and versions support changing the input field type. IE versions prior to 9 do not and will report the error "Could not get the type property. This command is not supported" if the following code is run:

document.getElementById('myPasswordField').type = 'text';

You'll get the above error message in IE6, IE7 and IE8, but it will work in all other browsers (including IE9) and will change the password field to a text field where you can see the typed in password in plain text.

Working example

Here's a working example using the code below. Type something into the password field below and then click the toggle button. If you are viewing this page in IE < 9 you won't see the toggle button. If you are viewing this in a feed reader you won't see it either, so click through to view the article in a web browser.

The HTML

Here's the HTML used in the example. Obviously your form would have additional inputs, such as a login or email address field, and a submit button.

<form>
	<input id="passwordField" type="password" name="passwordField" value="" autocomplete="off" />
	<input type="button" id="togglePasswordField" value="Toggle Password" style="display:none" />
</form>

Note the toggle button is hidden initially using CSS. I've coded it directly into the input button as part of this example, but you probably want to put it in your CSS file instead.

The Javascript

I'll post the Javascript as a big chunk here and then explain it after. I've written it entirely as plain old vanilla Javascript rather than relying on a library like jQuery. It needs to appear in your source code after the HTML form above. If it's in an external Javascript file, then that needs to be included after the form, e.g. at the very end of the document.

(function() {

	try {

		// switch the password field to text, then back to password to see if it supports
		// changing the field type (IE9+, and all other browsers do). then switch it back.
		var passwordField = document.getElementById('passwordField');
		passwordField.type = 'text';
		passwordField.type = 'password';
		
		// if it does support changing the field type then add the event handler and make
		// the button visible. if the browser doesn't support it, then this is bypassed
		// and code execution continues in the catch() section below
		var togglePasswordField = document.getElementById('togglePasswordField');
		togglePasswordField.addEventListener('click', togglePasswordFieldClicked, false);
		togglePasswordField.style.display = 'inline';
		
	}
	catch(err) {

	}

})();

function togglePasswordFieldClicked() {

	var passwordField = document.getElementById('passwordField');
	var value = passwordField.value;

	if(passwordField.type == 'password') {
		passwordField.type = 'text';
	}
	else {
		passwordField.type = 'password';
	}
	
	passwordField.value = value;

} 

The first section of the code sets everything up. It's in an anonymous function so the variables used only have local scope and don't interfere with any other already defined variables. The () at the end of the function declaration means it will run automatically without having to call it explicitly.

The try ... catch block is used to catch errors triggered by browsers that do not support input type changing (IE6,7,8) and prevent an error being displayed in the browser.

Lines 7 to 9 attempt to change the type of the password field to text and then back again to password. The browsers that don't support type changing will trigger an error and pass execution down to the catch() section.

Lines 14 to 16 add an event listener to the toggle button which calls the togglePasswordFieldClicked function whenever it is clicked, and then makes the button visible. The browsers that don't support type changing will never get this far and the button will remain invisible.

Finally, the togglePasswordFieldClicked function executes whenever the button is clicked. It checks to see what the current type is and changes it to the other.

Saving the current value and restoring it a few lines further down isn't really necessary, but in my testing Opera 9 (and presumably earlier) reset the value to an empty string each time the type is changed. For full compatibility I've added that code.

Browser compatibility

I've tested and the above code works in: Chrome, Safari 3.2+, IE9, FF 1.0+, Opera 9.0+, iPhone 3, iPhone 4, iPad 1.

It may work in older versions of Safari and Opera, but I don't have any installed to test and I think testing in those versions is old enough. The iPhone and iPads tested on were using the iPhone Simulator software and not actual hardware.

The toggling function doesn't work in IE6, IE7 or IE8, but as explained above the code has been created in a way which won't trigger errors and they degrade gracefully.



Related posts:


Comments