Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

433
Views
How to change password visibility when clicking outside of a password field

I am trying to create a password field that allows the user to click the eye icon to view or hide their password. However, on top of this, I would like to hide the password automatically when the user clicks outside the field. this requires a click and blur event. The problem is the blur event runs before the click event and runs when I click the eye icon. This causes the field to be toggled twice because it runs in the blur event block, then in the click event block.

I basically need it to allow me to toggle by clicking the eye icon and also set the field back to password type when exiting the field. I tried using onmousedown but it behaves really weird, it only works when I am stepping through on devtools.

function togglePassword(element) {
  $(element).toggleClass("fa-eye fa-eye-slash");

  $(element).siblings("input").each(function() {
    if ($(element).hasClass('fa-eye-slash')) {
      $(this).attr('type', 'text');
      $(this).focus();
    } else if ($(element).hasClass('fa-eye')) {
      $(this).attr('type', 'password');
    }
  });
}

function toggleWhenExiting(element) {
  console.log("focus toggle");

  $(element).siblings("span").each(function() {
    if ($(this).hasClass('fa-eye-slash')) {
      $(element).attr('type', 'password');
      $(this).toggleClass("fa-eye fa-eye-slash");
    }
  });
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css" integrity="sha512-Fo3rlrZj/k7ujTnHg4CGR2D7kSs0v4LLanw2qksYuRlEzO+tcaEPQogQ0KaoGN26/zrn20ImR1DfuLWnOo7aBA==" crossorigin="anonymous" referrerpolicy="no-referrer" />

<input type="password" id="passwordFirst" class="form-control" onblur="toggleWhenExiting(this)">
<span class="fas fa-eye" id="togglePassword" onclick="togglePassword(this)"></span>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

about 4 years ago · Juan Pablo Isaza
3 answers
Answer question

0

We can simplify and clarify things by using constants for the two elements and using jQuery's one() method to create an event handler that only fires once. Notice that I've removed all event handlers from the markup to modernize with separation of concerns.

We can also check the relatedTarget on blur and only take action if it's not the toggle button. Note that I've added tabindex="0" to that element to make it focusable. Without that it isn't reported as the blur target.

$('#togglePassword').click(function() {
  const eyeIcon = $(this);
  const pwdInput = $('#passwordFirst');

  pwdInput.off('blur');

  if (eyeIcon.hasClass('fa-eye')) {
    eyeIcon.removeClass('fa-eye').addClass('fa-eye-slash');
    pwdInput.attr('type', 'text').focus();

    pwdInput.one('blur', function(e) {
      if ($(e.relatedTarget).attr('id') !== 'togglePassword') {
        pwdInput.attr('type', 'password');
        eyeIcon.removeClass("fa-eye-slash").addClass('fa-eye');
      }
    });

  } else {
    eyeIcon.removeClass('fa-eye-slash').addClass('fa-eye');
    pwdInput.attr('type', 'password');
  }
});
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css" integrity="sha512-Fo3rlrZj/k7ujTnHg4CGR2D7kSs0v4LLanw2qksYuRlEzO+tcaEPQogQ0KaoGN26/zrn20ImR1DfuLWnOo7aBA==" crossorigin="anonymous" referrerpolicy="no-referrer"
/>

<input type="password" id="passwordFirst" class="form-control">
<span class="fas fa-eye" id="togglePassword" tabindex="0"></span>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

about 4 years ago · Juan Pablo Isaza Report

0

By monitoring time, repeated action could be detected. In the following code, the toggleWhenExiting function also calls the togglePassword function for toggling the view. The main key is preventing togglePassword function from running twice in less than 200ms. var timems = (new Date()).getTime() is used to get the time in ms and if(timems - $(element).attr('lastrun') < 200) return; calculate time distance from last run.

function togglePassword(element) {
  console.log("span clicked");
  var timems = (new Date()).getTime()
  if(timems - $(element).attr('lastrun') < 200)  return;
  $(element).attr('lastrun', timems);
  
  $(element).toggleClass("fa-eye fa-eye-slash");

  $(element).siblings("input").each(function() {
    if ($(element).hasClass('fa-eye-slash')) {
      $(this).attr('type', 'text');
      $(this).focus();
    } else if ($(element).hasClass('fa-eye')) {
      $(this).attr('type', 'password');
    }
  });
}

function toggleWhenExiting(element) {
  console.log("focus toggle");

  $(element).siblings("span").each(function() {
    if ($(this).hasClass('fa-eye-slash')) $(this).click();
  });
}
</script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css" integrity="sha512-Fo3rlrZj/k7ujTnHg4CGR2D7kSs0v4LLanw2qksYuRlEzO+tcaEPQogQ0KaoGN26/zrn20ImR1DfuLWnOo7aBA==" crossorigin="anonymous" referrerpolicy="no-referrer" />

<input type="password" id="passwordFirst" class="form-control" onblur="toggleWhenExiting(this)">
<span class="fas fa-eye" id="togglePassword" onclick="togglePassword(this)"></span>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

about 4 years ago · Juan Pablo Isaza Report

0

While I think I prefer isherwoods answer I'll leave this here for something else to think about

Here we use css to toggle the icon based on the type attribute of the preceding input element. A little use of the element inspector revealed the unicode for the content of the icon.

Next we use a div to combine the elements addingtabindex=0 again to make it "blurable". When this combined element loses focus, then set the input back to password

/*Toggle password field on eye click*/
$(".togglePassword > .fas").click(function() {
  //Get currnet status
  var currentType = $(this).prev("input").attr("type");
  //toggle the password field
  $(this).prev("input").attr("type", currentType == "password" ? "text" : "password");
})

/*Set back to password when our combined element loses focus*/
$(".togglePassword").blur(function() {
  $(this).find("input").attr("type", "password");
})
/*Use CSS to toggle the eye icon based on type attribute of previous element*/
.togglePassword>[type=password]+.fas::before {
  /*eye icon*/
  content: "\f06e";
}

.togglePassword>[type=text]+.fas::before {
  /*slashed eye icon*/
  content: "\f070";
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css" integrity="sha512-Fo3rlrZj/k7ujTnHg4CGR2D7kSs0v4LLanw2qksYuRlEzO+tcaEPQogQ0KaoGN26/zrn20ImR1DfuLWnOo7aBA==" crossorigin="anonymous" referrerpolicy="no-referrer"
/>
<div class="togglePassword" tabindex="0">
  <input type="password" id="passwordFirst" class="form-control"> <span class="fas"></span>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!