Background
I very recently coded up some views for new members on a site to register, to change their passwords, and in one user story, for administrative members to sign up other members, and be able to set temporary passwords for them. I’ve always prefered a UI that allows an option for passwords to be visible, and I thought I’d offer my users that option. It also helps a bit having it myself when I do some manual testing.
Using the Code
Here is the somewhat hackish solution I came up with. I am no jQuery wizard, but this code seems to work just fine.
function copyDataAttributes(source, destination) {
for (var i = 0; i < source.attributes.length; i++) {
var a = source.attributes[i];
if (a.name.indexOf("data-") == 0) {
destination.attr(a.name, a.value);
}
}
}
function setPasswordVisibility() {
if ($("#PasswordsVisible").is(':checked')) {
$('form').find('input:password').each(function() {
var newText = $("");
copyDataAttributes(this, newText);
newText.attr({ id: $(this).attr("id"),
name: $(this).attr("name"), value: $(this).attr("value") })
.addClass("password").bind('copy', function() { return false; })
.insertBefore(this);
}).remove();
} else {
$('form').find('input:text.password').each(function() {
var newPassword = $("");
copyDataAttributes(this, newPassword);
newPassword.attr({ id: $(this).attr("id"),
name: $(this).attr("name"), value: $(this).attr("value") })
.insertBefore(this);
}).remove();
}
}
jQuery(function () {
setPasswordVisibility();
$("#PasswordsVisible").click(function () {
setPasswordVisibility();
});
});
Points of Interest
My main function, setPasswordVisibility
, checks if passwords should be visible or not, and if so, sets about making them visible. Initially, I though this would be as easy as changing the type of an input from ‘password’ to ‘text’, but changing the type attribute is simply not allowed. Some research found an acceptable workaround in replacing a ‘password’ type input with an almost identical ‘text’ type input. This is of course reversed and a ‘text’ input replaced with a ‘password’ one to hide a password again.
What complicates matters here is having two inputs for the password, with one for confirmation, so I brutishly applied this to all passwords on a form. Feel free to add some finesse and narrow down the target. Further complications are provided by the ‘data-‘ validation attributes that MVC scaffolding adds to elements based on model metadata; in this case stuff used to compare the two password fields using jQuery validation. I didn’t want to copy all attributes, but I felt safe copying all ‘data-‘ attributes, as they are for all intents and purposes my domain, and not that of the DOM.
Notice that when I turn a ‘password’ input into a ‘text’ input, I add a ‘password’ class to it, so when I hide passwords again, I don’t just hide all text inputs.
What happens here is when the page loads, I grab the click event of a checkbox that you would use check to make passwords visible. I also run the main function independently of the click event, because the checkbox might already be checked.
History
An old article moved from a blog I am retiring.