change type of input field with jQuery

JavascriptJqueryHtml Input

Javascript Problem Overview


$(document).ready(function() {
    // #login-box password field
    $('#password').attr('type', 'text');
    $('#password').val('Password');
});

This is supposed to change the #password input field (with id="password") that is of type password to a normal text field, and then fill in the text “Password”.

It doesn’t work, though. Why?

Here is the form:

<form enctype="application/x-www-form-urlencoded" method="post" action="/auth/sign-in">
  <ol>
    <li>
      <div class="element">
        <input type="text" name="username" id="username" value="Prihlasovacie meno" class="input-text" />
      </div>
    </li>
    <li>
      <div class="element">
        <input type="password" name="password" id="password" value="" class="input-text" />
      </div>
    </li>
    <li class="button">
      <div class="button">
        <input type="submit" name="sign_in" id="sign_in" value="Prihlásiť" class="input-submit" />
      </div>
    </li>
  </ol>
</form>

Javascript Solutions


Solution 1 - Javascript

It's very likely this action is prevented as part of the browser's security model.

Edit: indeed, testing right now in Safari, I get the error type property cannot be changed.

Edit 2: that seems to be an error straight out of jQuery. Using the following straight DOM code works just fine:

var pass = document.createElement('input');
pass.type = 'password';
document.body.appendChild(pass);
pass.type = 'text';
pass.value = 'Password';

Edit 3: Straight from the jQuery source, this seems to be related to IE (and could either be a bug or part of their security model, but jQuery isn't specific):

// We can't allow the type property to be changed (since it causes problems in IE)
if ( name == "type" && jQuery.nodeName( elem, "input" ) && elem.parentNode )
    throw "type property can't be changed";

Solution 2 - Javascript

One step solution

$('#password').get(0).type = 'text';

Solution 3 - Javascript

Even easier... there's no need for all the dynamic element creation. Just create two separate fields, making one the 'real' password field (type="password") and one a 'fake' password field (type="text"), setting the text in the fake field to a light gray color and setting the initial value to 'Password'. Then add a few lines of Javascript with jQuery as below:

    <script type="text/javascript">

		function pwdFocus() {
			$('#fakepassword').hide();
			$('#password').show();
			$('#password').focus();
		}
		
		function pwdBlur() {
			if ($('#password').attr('value') == '') {
				$('#password').hide();
				$('#fakepassword').show();
			}
		}
	</script>
	
	<input style="color: #ccc" type="text" name="fakepassword" id="fakepassword" value="Password" onfocus="pwdFocus()" />
    <input style="display: none" type="password" name="password" id="password" value="" onblur="pwdBlur()" />

So when the user enters the 'fake' password field it will be hidden, the real field will be shown, and the focus will move to the real field. They will never be able to enter text in the fake field.

When the user leaves the real password field the script will see if it's empty, and if so will hide the real field and show the fake one.

Be careful not to leave a space between the two input elements because IE will position one a little bit after the other (rendering the space) and the field will appear to move when the user enters/exits it.

Solution 4 - Javascript

Nowadays, you can just use

$("#password").prop("type", "text");

But of course, you should really just do this

<input type="password" placeholder="Password" />

in all but IE. There are placeholder shims out there to mimic that functionality in IE as well.

Solution 5 - Javascript

A more cross-browser solution… I hope the gist of this helps someone out there.

This solution tries to set the type attribute, and if it fails, it simply creates a new <input> element, preserving element attributes and event handlers.

changeTypeAttr.js (GitHub Gist):

/* x is the <input/> element
   type is the type you want to change it to.
   jQuery is required and assumed to be the "$" variable */
function changeType(x, type) {
    x = $(x);
    if(x.prop('type') == type)
        return x; //That was easy.
    try {
        return x.prop('type', type); //Stupid IE security will not allow this
    } catch(e) {
        //Try re-creating the element (yep... this sucks)
        //jQuery has no html() method for the element, so we have to put into a div first
        var html = $("<div>").append(x.clone()).html();
        var regex = /type=(\")?([^\"\s]+)(\")?/; //matches type=text or type="text"
        //If no match, we add the type attribute to the end; otherwise, we replace
        var tmp = $(html.match(regex) == null ?
            html.replace(">", ' type="' + type + '">') :
            html.replace(regex, 'type="' + type + '"') );
        //Copy data from old element
        tmp.data('type', x.data('type') );
        var events = x.data('events');
        var cb = function(events) {
            return function() {
                //Bind all prior events
                for(i in events)
                {
                    var y = events[i];
                    for(j in y)
                        tmp.bind(i, y[j].handler);
                }
            }
        }(events);
        x.replaceWith(tmp);
        setTimeout(cb, 10); //Wait a bit to call function
        return tmp;
    }
}

Solution 6 - Javascript

This works for me.

$('#password').replaceWith($('#password').clone().attr('type', 'text'));

Solution 7 - Javascript

An ultimate way to use jQuery:


Leave the original input field hidden from the screen.

$("#Password").hide(); //Hide it first
var old_id = $("#Password").attr("id"); //Store ID of hidden input for later use
$("#Password").attr("id","Password_hidden"); //Change ID for hidden input

Create new input field on the fly by JavaScript.

var new_input = document.createElement("input");

Migrate the ID and value from hidden input field to the new input field.

new_input.setAttribute("id", old_id); //Assign old hidden input ID to new input
new_input.setAttribute("type","text"); //Set proper type
new_input.value = $("#Password_hidden").val(); //Transfer the value to new input
$("#Password_hidden").after(new_input); //Add new input right behind the hidden input

To get around the error on IE like type property cannot be changed, you may find this useful as belows:

Attach click/focus/change event to new input element, in order to trigger the same event on hidden input.

$(new_input).click(function(){$("#Password_hidden").click();});
//Replicate above line for all other events like focus, change and so on...

Old hidden input element is still inside the DOM so will react with the event triggered by new input element. As ID is swapped, new input element will act like the old one and respond to any function call to old hidden input's ID, but looks different.

> A little bit tricky but WORKS!!! ;-)

Solution 8 - Javascript

Have you tried using .prop()?

$("#password").prop('type','text');

http://api.jquery.com/prop/

Solution 9 - Javascript

I haven't tested in IE (since I needed this for an iPad site) - a form I couldn't change the HTML but I could add JS:

document.getElementById('phonenumber').type = 'tel';

(Old school JS is ugly next to all the jQuery!)

But, http://bugs.jquery.com/ticket/1957 links to MSDN: "As of Microsoft Internet Explorer 5, the type property is read/write-once, but only when an input element is created with the createElement method and before it is added to the document." so maybe you could duplicate the element, change the type, add to DOM and remove the old one?

Solution 10 - Javascript

This Worked for me.

$('#newpassword_field').attr("type", 'text');

Solution 11 - Javascript

Just create a new field to bypass this security thing:

var $oldPassword = $("#password");
var $newPassword = $("<input type='text' />")
                          .val($oldPassword.val())
                          .appendTo($oldPassword.parent());
$oldPassword.remove();
$newPassword.attr('id','password');

Solution 12 - Javascript

I received the same error message while attempting to do this in Firefox 5.

I solved it using the code below:

<script type="text/javascript" language="JavaScript">

$(document).ready(function()
{
    var passfield = document.getElementById('password_field_id');
    passfield.type = 'text';
});

function focusCheckDefaultValue(field, type, defaultValue)
{
    if (field.value == defaultValue)
    {
        field.value = '';
    }
    if (type == 'pass')
    {
        field.type = 'password';
    }
}
function blurCheckDefaultValue(field, type, defaultValue)
{
    if (field.value == '')
    {
        field.value = defaultValue;
    }
    if (type == 'pass' && field.value == defaultValue)
    {
        field.type = 'text';
    }
    else if (type == 'pass' && field.value != defaultValue)
    {
        field.type = 'password';
    }
}

</script>

And to use it, just set the onFocus and onBlur attributes of your fields to something like the following:

<input type="text" value="Username" name="username" id="username" 
    onFocus="javascript:focusCheckDefaultValue(this, '', 'Username -OR- Email Address');"
    onBlur="javascript:blurCheckDefaultValue(this, '', 'Username -OR- Email Address');">

<input type="password" value="Password" name="pass" id="pass"
    onFocus="javascript:focusCheckDefaultValue(this, 'pass', 'Password');"
    onBlur="javascript:blurCheckDefaultValue(this, 'pass', 'Password');">

I use this for a username field as well, so it toggles a default value. Just set the second parameter of the function to '' when you call it.

Also it might be worth noting that the default type of my password field is actually password, just in case a user doesn't have javascript enabled or if something goes wrong, that way their password is still protected.

The $(document).ready function is jQuery, and loads when the document has finished loading. This then changes the password field to a text field. Obviously you'll have to change 'password_field_id' to your password field's id.

Feel free to use and modify the code!

Hope this helps everyone who had the same problem I did :)

-- CJ Kent

EDIT: Good solution but not absolute. Works on on FF8 and IE8 BUT not fully on Chrome(16.0.912.75 ver). Chrome does not display the Password text when the page loads. Also - FF will display your password when autofill is switched on.

Solution 13 - Javascript

Simple solution for all those who want the functionality in all browsers:

HTML

<input type="password" id="password">
<input type="text" id="passwordHide" style="display:none;">
<input type="checkbox" id="passwordSwitch" checked="checked">Hide password

jQuery

$("#passwordSwitch").change(function(){
	var p = $('#password');
	var h = $('#passwordHide');
	h.val(p.val());
	if($(this).attr('checked')=='checked'){
		h.hide();
		p.show();
	}else{
		p.hide();
		h.show();
	}
});

Solution 14 - Javascript

Type properties can't be changed you need to replace or overlay the input with a text input and send the value to the password input on submit.

Solution 15 - Javascript

I guess you could use a background-image that contains the word "password" and change it back to an empty background-image on .focus().

.blur() ----> image with "password"

.focus() -----> image with no "password"

You could also do it with some CSS and jQuery. Have a text field show up exactly on top of the password field, hide() is on focus() and focus on the password field...

Solution 16 - Javascript

Try this
Demo is here

$(document).delegate('input[type="text"]','click', function() {
    $(this).replaceWith('<input type="password" value="'+this.value+'" id="'+this.id+'">');
}); 
$(document).delegate('input[type="password"]','click', function() {
    $(this).replaceWith('<input type="text" value="'+this.value+'" id="'+this.id+'">');
}); 

Solution 17 - Javascript

It works much easier with that:

document.querySelector('input[type=password]').setAttribute('type', 'text');

and in order to turn it back to password field again,(assuming the password field is the 2nd input tag with text type):

document.querySelectorAll('input[type=text]')[1].setAttribute('type', 'password')

Solution 18 - Javascript

use this one it is very easy

<input id="pw" onclick="document.getElementById('pw').type='password';
  document.getElementById('pw').value='';"
  name="password" type="text" value="Password" />

Solution 19 - Javascript

$('#pass').focus(function() { 
$('#pass').replaceWith("<input id='password' size='70' type='password' value='' name='password'>");
$('#password').focus();
});

<input id='pass' size='70' type='text' value='password' name='password'>

Solution 20 - Javascript

Here is a little snippet that allows you to change the type of elements in documents.

jquery.type.js (GitHub Gist):

var rtype = /^(?:button|input)$/i;

jQuery.attrHooks.type.set = function(elem, value) {
    // We can't allow the type property to be changed (since it causes problems in IE)
    if (rtype.test(elem.nodeName) && elem.parentNode) {
        // jQuery.error( "type property can't be changed" );

        // JB: Or ... can it!?
        var $el = $(elem);
        var insertionFn = 'after';
        var $insertionPoint = $el.prev();
        if (!$insertionPoint.length) {
            insertionFn = 'prepend';
            $insertionPoint = $el.parent();
        }

        $el.detach().attr('type', value);
        $insertionPoint[insertionFn]($el);
        return value;

    } else if (!jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input")) {
        // Setting the type on a radio button after the value resets the value in IE6-9
        // Reset value to it's default in case type is set after value
        // This is for element creation
        var val = elem.value;
        elem.setAttribute("type", value);
        if (val) {
            elem.value = val;
        }
        return value;
    }
}

It gets around the issue by removing the input from the document, changing the type and then putting it back where it was originally.

Note that this snippet was only tested for WebKit browsers – no guarantees on anything else!

Solution 21 - Javascript

jQuery.fn.outerHTML = function() {
	return $(this).clone().wrap('<div>').parent().html();
};
$('input#password').replaceWith($('input.password').outerHTML().replace(/text/g,'password'));

Solution 22 - Javascript

This will do the trick. Although it could be improved to ignore attributes that are now irrelevant.

Plugin:

(function($){
  $.fn.changeType = function(type) {  
    return this.each(function(i, elm) {
        var newElm = $("<input type=\""+type+"\" />");
        for(var iAttr = 0; iAttr < elm.attributes.length; iAttr++) {
            var attribute = elm.attributes[iAttr].name;
            if(attribute === "type") {
                continue;
            }
            newElm.attr(attribute, elm.attributes[iAttr].value);
        }
        $(elm).replaceWith(newElm);
    });
  };
})(jQuery);

Usage:

$(":submit").changeType("checkbox");

Fiddle:

http://jsfiddle.net/joshcomley/yX23U/

Solution 23 - Javascript

Simply this:

this.type = 'password';

such as

$("#password").click(function(){
	this.type = 'password';
});

This is assuming that your input field was set to "text" before hand.

Solution 24 - Javascript

Here is a method which uses an image next to the password field to toggle between seeing the password (text input) and not seeing it (password input). I use an "open eye" and "closed eye" image, but you can use whatever suits you. The way it works is having two inputs/images and upon clicking the image, the value is copied from the visible input to the hidden one, and then their visibility is swapped. Unlike many of the other answers which use hardcoded names, this one is general enough to use it multiple times on a page. It also degrades gracefully if JavaScript is unavailable.

Here is what two of these look like on a page. In this example, the Password-A has been revealed by clicking on its eye.

How it looks

$(document).ready(function() {
  $('img.eye').show();
  $('span.pnt').on('click', 'img', function() {
    var self = $(this);
    var myinp = self.prev();
    var myspan = self.parent();
    var mypnt = myspan.parent();
    var otspan = mypnt.children().not(myspan);
    var otinp = otspan.children().first();
    otinp.val(myinp.val());
    myspan.hide();
    otspan.show();
  });
});

img.eye {
  vertical-align: middle;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<form>
<b>Password-A:</b>
<span class="pnt">
<span>
<input type="password" name="passa">
<img src="eye-open.png" class="eye" alt="O" style="display:none">
</span>
<span style="display:none">
<input type="text">
<img src="eye-closed.png" class="eye" alt="*">
</span>
</span>
</form>

<form>
<b>Password-B:</b>
<span class="pnt">
<span>             
<input type="password" name="passb">
<img src="eye-open.png" class="eye" alt="O" style="display:none">
</span> 
<span style="display:none">            
<input type="text">
<img src="eye-closed.png" class="eye" alt="*">
</span> 
</span>
</form>

Solution 25 - Javascript

I just did the following to change the type of an input:

$('#ID_of_element')[0].type = 'text';

and it works.

I was needing to do this because I was using jQuery UI datepickers' in an ASP NET Core 3.1 project and they were not working properly on Chromium-based browsers (see: https://stackoverflow.com/a/61296225/7420301).

Solution 26 - Javascript

I like this way, to change the type of an input element: old_input.clone().... Here is an example. There is an check box "id_select_multiple". If this is is changed to "selected", input elements with name "foo" should be changed to check boxes. If it gets unchecked, they should be become radio buttons again.

  $(function() {
    $("#id_select_multiple").change(function() {
     var new_type='';
     if ($(this).is(":checked")){ // .val() is always "on"
          new_type='checkbox';
     } else {
         new_type="radio";
     }
     $('input[name="foo"]').each(function(index){
         var new_input = $(this).clone();
         new_input.attr("type", new_type);
         new_input.insertBefore($(this));
         $(this).remove();
     });
    }
  )});

Solution 27 - Javascript

heres a DOM solution

myInput=document.getElementById("myinput");
oldHtml=myInput.outerHTML;
text=myInput.value;
newHtml=oldHtml.replace("password","text");
myInput.outerHTML=newHtml;
myInput=document.getElementById("myinput");
myInput.value=text;

Solution 28 - Javascript

I've created a jQuery extension to toggle between text and password. Works in IE8 (probably 6&7 as well, but not tested) and won't lose your value or attributes:

$.fn.togglePassword = function (showPass) {
	return this.each(function () {
		var $this = $(this);
		if ($this.attr('type') == 'text' || $this.attr('type') == 'password') {
			var clone = null;
			if((showPass == null && ($this.attr('type') == 'text')) || (showPass != null && !showPass)) {
				clone = $('<input type="password" />');
			}else if((showPass == null && ($this.attr('type') == 'password')) || (showPass != null && showPass)){
				clone = $('<input type="text" />');
			}
			$.each($this.prop("attributes"), function() {
				if(this.name != 'type') {
					clone.attr(this.name, this.value);
				}
			});
			clone.val($this.val());
			$this.replaceWith(clone);
		}
	});
};

Works like a charm. You can simply call $('#element').togglePassword(); to switch between the two or give an option to 'force' the action based on something else (like a checkbox): $('#element').togglePassword($checkbox.prop('checked'));

Solution 29 - Javascript

Just another option for all the IE8 lovers, and it works perfect in newer browsers. You can just color the text to match the background of the input. If you have a single field, this will change the color to black when you click/focus on the field. I would not use this on a public site since it would 'confuse' most people, but I am using it in an ADMIN section where only one person has access to the users passwords.

$('#MyPass').click(function() {
    $(this).css('color', '#000000');
});

-OR-

$('#MyPass').focus(function() {
    $(this).css('color', '#000000');
});

This, also needed, will change the text back to white when you leave the field. Simple, simple, simple.

$("#MyPass").blur(function() {
    $(this).css('color', '#ffffff');
});

[ Another Option ] Now, if you have several fields that you are checking for, all with the same ID, as I am using it for, add a class of 'pass' to the fields you want to hide the text in. Set the password fields type to 'text'. This way, only the fields with a class of 'pass' will be changed.

<input type="text" class="pass" id="inp_2" value="snoogle"/>

$('[id^=inp_]').click(function() {
    if ($(this).hasClass("pass")) {
        $(this).css('color', '#000000');
    }
    // rest of code
});

Here is the second part of this. This changes the text back to white after you leave the field.

$("[id^=inp_]").blur(function() {
    if ($(this).hasClass("pass")) {
        $(this).css('color', '#ffffff');
    }
    // rest of code
});

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRichard KnopView Question on Stackoverflow
Solution 1 - JavascripteyelidlessnessView Answer on Stackoverflow
Solution 2 - JavascriptSanket SahuView Answer on Stackoverflow
Solution 3 - JavascriptJoeView Answer on Stackoverflow
Solution 4 - JavascriptAndrewView Answer on Stackoverflow
Solution 5 - JavascriptBMinerView Answer on Stackoverflow
Solution 6 - JavascriptstephenmussView Answer on Stackoverflow
Solution 7 - JavascriptKen PegaView Answer on Stackoverflow
Solution 8 - JavascriptMark MckelvieView Answer on Stackoverflow
Solution 9 - JavascripthoodView Answer on Stackoverflow
Solution 10 - JavascriptAshhabView Answer on Stackoverflow
Solution 11 - JavascriptjantimonView Answer on Stackoverflow
Solution 12 - Javascriptcjk84View Answer on Stackoverflow
Solution 13 - JavascripthohnerView Answer on Stackoverflow
Solution 14 - JavascriptJesse KochisView Answer on Stackoverflow
Solution 15 - JavascriptrhodiumView Answer on Stackoverflow
Solution 16 - JavascriptSuresh PattuView Answer on Stackoverflow
Solution 17 - JavascriptSedat KilincView Answer on Stackoverflow
Solution 18 - JavascriptFarhanView Answer on Stackoverflow
Solution 19 - JavascriptvankaiserView Answer on Stackoverflow
Solution 20 - Javascriptjb.View Answer on Stackoverflow
Solution 21 - JavascriptunlocoView Answer on Stackoverflow
Solution 22 - JavascriptjoshcomleyView Answer on Stackoverflow
Solution 23 - JavascriptMichaelView Answer on Stackoverflow
Solution 24 - JavascriptJohn HascallView Answer on Stackoverflow
Solution 25 - JavascriptPablo Alexis Domínguez GrauView Answer on Stackoverflow
Solution 26 - JavascriptguettliView Answer on Stackoverflow
Solution 27 - JavascriptchiliNUTView Answer on Stackoverflow
Solution 28 - JavascriptJ_A_XView Answer on Stackoverflow
Solution 29 - JavascriptTom aka SparkyView Answer on Stackoverflow