Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.
Ben Nadel at NCDevCon 2016 (Raleigh, NC) with: Matthew Eash
Ben Nadel at NCDevCon 2016 (Raleigh, NC) with: Matthew Eash@mujimu )

Implementing A "Show Password" Checkbox On A Login Form In JavaScript

By Ben Nadel on

More and more, I've been seeing a pattern emerging on login forms where the user is presented with a "show password" toggle. Clicking on this toggle will change the password field from an obfuscated input to a plain-text input where the user can clearly see what value they are typing. Now, if you're old like me, you remember a time where some browsers (*cough* IE *cough*) wouldn't allow input "type" properties to be changed after an input was added to the DOM (Document Object Model). As such, I thought it would be fun to see how easy it is in the modern browser landscape to implement one of these "show password" checkboxes on a login form.


 
 
 

 
 
 
 
 

Run this demo in my JavaScript Demos project on GitHub.

View this code in my JavaScript Demos project on GitHub.

Both a plain-text input and a password input are just that: input elements. The only thing that differentiates them is the "type" property (and attribute). Once you have a reference to one of these inputs, you can programmatically change the "type" property which will, in turn, change the way the element is rendered in the DOM.

To see this in action, I've put together a mock login form that has a username and a password field. The password field starts out as a type="password"; but, will change to a type="text" if the user clicks a "Show Password" toggle:

  • <!doctype html>
  • <html lang="en">
  • <head>
  • <meta charset="utf-8" />
  • <title>
  • Implementing A "Show Password" Checkbox On A Login Form In JavaScript
  • </title>
  •  
  • <link rel="stylesheet" type="text/css" href="./demo.css" />
  • </head>
  • <body>
  •  
  • <h1>
  • Implementing A "Show Password" Checkbox On A Login Form In JavaScript
  • </h1>
  •  
  • <!-- NOTE: Using GET so we can see the results in the URL. -->
  • <form method="get" action="./" class="login">
  •  
  • <div class="login__field field">
  • <label for="username" class="field__label">
  • Username:
  • </label>
  • <input type="text" id="username" name="username" class="field__input" />
  • </div>
  •  
  • <div class="login__field field">
  • <label for="password" class="field__label">
  • Password:
  • </label>
  • <input type="password" id="password" name="password" class="field__input" />
  •  
  • <label for="show-password" class="field__toggle">
  • <input type="checkbox" id="show-password" class="field__toggle-input" />
  • Show password
  • </label>
  • </div>
  •  
  • <div class="login__actions actions">
  • <button type="submit" class="actions__button">
  • Login + Start Rocking &raquo;
  • </button>
  • </div>
  •  
  • </form>
  •  
  • <script type="text/javascript">
  •  
  • // Gather our DOM references.
  • var username = document.querySelector( "#username" );
  • var password = document.querySelector( "#password" );
  • var toggle = document.querySelector( "#show-password" );
  •  
  • // Set some default values just to make the demo easier to use.
  • username.value = "BenJamin2002";
  • password.value = "dontTazeMeBro!";
  •  
  • // NOTE: The "(input)" event doesn't work on checkboxes in Safari or IE. As such,
  • // I'm using the "(click)" event to make this works cross-browser.
  • toggle.addEventListener( "click", handleToggleClick, false );
  •  
  • // --------------------------------------------------------------------------- //
  • // --------------------------------------------------------------------------- //
  •  
  • // I handle the toggle click, changing the TYPE of password input.
  • function handleToggleClick( event ) {
  •  
  • if ( this.checked ) {
  •  
  • console.warn( "Change input 'type' to: text" );
  • password.type = "text";
  •  
  • } else {
  •  
  • console.warn( "Change input 'type' to: password" );
  • password.type = "password";
  •  
  • }
  •  
  • }
  •  
  • </script>
  •  
  • </body>
  • </html>

As you can see, there's really not much going on here at all. Ninety-percent of this demo is just HTML markup and CSS. The only relevant logic is the click-handler, which - as you can see - just changes the "type" property of the input based on the state of the "show password" checkbox. And, if we load this page and click the "show password" toggle, we get the following output:


 
 
 

 
 Implementing a show password checkbox on a login form in JavaScript. 
 
 
 

As you can see, the password field changed from an obfuscated field into a plain-text field. Easy peasy!

As passwords get longer and more complex, typing them in becomes more and more error-prone. This is especially true when you're inputting values that aren't in a password manager. For example, the password on the bottom of your friend's router, or the temporary WiFi password they give you at a hotel. In such cases, being able to toggle the obfuscation of the password field can reduce the headache of failed logins. Luckily, with modern browsers, it's quite easy to implement a "show password" checkbox on a login form using JavaScript.


Looking For A New Job?

Ooops, there are no jobs. Post one now for only $29 and own this real estate!

100% of job board revenue is donated to Kiva. Loans that change livesFind out more »

Reader Comments

If you submit the form while the password is "visible" would this negate the browser's ability to save the password to your keychain? ??

Reply to this Comment

@Chesley,

Oooooh, that's a super interesting question. Full disclosure, I never store my passwords in the browser, so I don't have a good gut-instinct on that. That said, you should be able to bind to the (submit) even to the form and swap the type property back to password. This should, in my best estimate, revert the form to the "normal" relationship with the browser.

I'll have to try that and see if the browser prompts me to save the password.

Great question!

Reply to this Comment

What should happen when a registered user visits the login page, and the browser autofills the password field? I think, "Show password" should be disabled in this scenario. But how do you detect autofill, reliably?

Reply to this Comment

@Šime,

Hmm, that's an interesting idea. Though, I am not sure that it will actually protect anything. Once the page has rendered and the form has been auto-filled, as long as it hasn't been submitted, you should be able to just inspect the DOM, select the password input, and console.log( $0.value ). In other words, I don't think that the "show password" feature removes any implicit security from the page.

Really, the only security risk - from what I understand - is other people peering over your shoulder.

Reply to this Comment

@Ben,

It will protect your password from people who don't know how to use DevTools, which is like 99% of people ??

Example scenario: a friend or college uses your computer or smartphone for a few minutes. They land on a login page for whatever reason, and the browser autofills the password field. They see the "Show password" control, and out of curiosity, they use it. Now they've seen your password.

Of course, if a person with malicious intent and sufficient skill gets access to your browser, it's pretty much over. They can do great damage. But I'm talking about scenarios where your password is needlessly exposed to people who didn't want to steal your password but saw it out of curiosity because the opportunity arose.

The key word is needlessly. There is no reason why "Show password" should be active for autofilled passwords. It just overexposes the password.

Reply to this Comment

@Šime,

Very interesting. I'm not against that perspective. And, I agree that nothing should be done needlessly, especially when security is a concern. I'll have to mull that over. Now I am curious to see if there is any way to detect "autofill" of an input. I'll have to do some research on that.

Regarding the ??. Not sure why that happened. It's very possible that my comments are stored at utf8 and not utf8mb4, which would be needed for some "astral plane" emoji characters. This is an old issue with my database.

Reply to this Comment

Post A Comment

You — Get Out Of My Dreams, Get Into My Comments
Live in the Now
Oops!
NEW: Some basic markdown formatting is now supported: bold, italic, blockquotes, lists, fenced code-blocks. Read more about markdown syntax »
Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.