Forum Moderators: open

Message Too Old, No Replies

jQuery: toggling input password to text

         

csdude55

8:56 pm on Mar 9, 2021 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I've had a few requests from users to offer the toggle option so they can see what they're typing. I know that IE was having a problem with this before, but I'm not sure if that's still true or how far back I need to worry about it.

Is there any practical reason to not simply use:

// HTML
<input type="password">
<a class="toggler">toggle</a>

// jQuery
$('a.toggler')
.click(function() {
var prev = $(this).prev('input');

if (prev.prop('type') === 'password')
prev.prop('type', 'text');

else
prev.prop('type', 'password');
});

or, is there a way to test compatibility before running it?

csdude55

5:26 am on Mar 10, 2021 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Doubling down... it looks like at least the most recent Edge is cool with it, but I'm not sure about older versions. BUT! Edge takes it a step further and has its own built-in toggler! When you start typing in a password field, the eye automatically pops up for you to toggle it.

So now I'm at a different question... how to test if the user's browser is going to show this automatically? If not then I guess I'd show my own image to make it look the same. I can't just check for IE, though, because I can imagine that future versions of any of them might include this.

csdude55

8:22 pm on Mar 12, 2021 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I haven't found a way to test for compatibility or conflicts, so all I have at this point is testing the userAgent.

if (!navigator.userAgent.match(/MSIE|Trident|Edge/)) {
$('a.toggler').addClass('showEye', 'eyeOn');

$('.showEye')
.click(function() {
var prev = $(this).prev('input');

if (prev.prop('type') === 'password') {
prev.prop('type', 'text');

$(this)
.removeClass('eyeOn')
.addClass('eyeOff');
}

else {
prev.prop('type', 'password');

$(this)
.removeClass('eyeOff')
.addClass('eyeOn');
}
});
}


Here's the functioning fiddle, but it uses flex and I'm not in love with the vertical centering:
[jsfiddle.net...]

I'd love to find a better, more permanent solution that actually tests for compatibility, though!

robzilla

7:17 am on Mar 13, 2021 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



This is supported since IE9, so I wouldn't worry about compatibility. It's practically impossible to browse the modern Web using <IE9.

Instead of testing the user agent, you could simply hide the native password reveal icon in IE/Edge using ::ms-reveal:
Customize the password reveal button [docs.microsoft.com]

csdude55

6:34 pm on Mar 14, 2021 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



How did you find how far down it's compatible, @robzilla? I haven't been able to think of anything to test for to find out!

But trusting you on that one, now I'm down to:

// CSS
::-ms-reveal { display: none }

// jQuery
if (!navigator.userAgent.indexOf('MSIE') !== -1) {
$('a.toggler').addClass('showEye', 'eyeOn');

$('.showEye')
.click(function() {
var prev = $(this).prev('input');

if (prev.prop('type') === 'password') {
prev.prop('type', 'text');

$(this)
.removeClass('eyeOn')
.addClass('eyeOff');
}

else {
prev.prop('type', 'password');

$(this)
.removeClass('eyeOff')
.addClass('eyeOn');
}
});
}


I recognize that testing for MSIE will match IE 9 and 10, too, so this would be more exact but it's marginally slower for everyone and I'm not sure if it's worth it:

var ie = (navigator.userAgent.indexOf('MSIE') !== -1) ?
parseInt(navigator.userAgent.split('MSIE')[1]) :
false;

if (!ie || ie <= 9) {
$('a.toggler').addClass('showEye', 'eyeOn');

$('.showEye')
.click(function() {
var prev = $(this).prev('input');

if (prev.prop('type') === 'password') {
prev.prop('type', 'text');

$(this)
.removeClass('eyeOn')
.addClass('eyeOff');
}

else {
prev.prop('type', 'password');

$(this)
.removeClass('eyeOff')
.addClass('eyeOn');
}
});
}

robzilla

9:22 pm on Mar 14, 2021 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Haven't tested it myself, it's just what I read in various places when I did a bit of research on it.

What may also be relevant here is that jQuery does not officially support versions of IE below 9.

You could try to swap them out, then check if the swap was actually completed, to detect support. Might throw an error on old versions of IE, though.

Have you checked how many of your users are actually on IE 8 or 9? Assuming your site has a modern HTTPS configuration, IE8 users likely won't be able to access it at all.

csdude55

3:52 am on Mar 15, 2021 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



It's probably totally irrelevant at this point; last month, my main site had 2 users with IE9 (average 10.5 pages /session) and 1 with IE7 (2 pages /session). January saw 1 users with IE9, and none with IE8 or 7. So I think I can safely just test for MSIE and be done with it.

If .addClass() was ignored by <= IE9 then that would be great, I wouldn't have to test at all! But apparently it is :-(