change type of input field with jQuery
Asked Answered
S

30

217
$(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>
Singleness answered 9/10, 2009 at 14:54 Comment(3)
Why do you want to change it?Mate
I want to have a user firendly 'Password' text in the input so the users know what to fill in (because there is no label).Singleness
Check this video: youtube.com/watch?v=5YeSqtB0kfEPlop
D
263

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";
Disillusionize answered 9/10, 2009 at 14:57 Comment(6)
gotta say, this is the most useless security measurement I've ever seen. There doesn't seem to be that much of a difference between quickly changing the type of a field and replacing it with a totally new one. Very strange ... anyway, worked for me. Thanks!Roots
its not security model stuff, I can confirm that it doesn't work in IE7, IE8 with error: Could not get the type propertyPlanchet
Found this answer on a search and it was a great help. However, my solution was to just remove that check from jquery. Worked great.Palladin
@Michael, I'd recommend against altering jQuery directly. Besides that it creates a conflict liability going forward, that check is probably in place for a reason. If you don't need to worry about IE support, you could instead implement a jQuery extension that parallels attr but allows changing the type attribute on input elements.Disillusionize
Just added update 4 - hope it helps explain things and how to get around them.Blitzkrieg
@ClarkeyBoy, I rolled back the edit because I would not ever recommend modifying a vendor file. The problem is clear—old versions of IE break when modifying an input type. The answer clearly demonstrates that. Another question might ask how to work around this limitation, but that is outside the scope of this question.Disillusionize
C
89

One step solution

$('#password').get(0).type = 'text';
Carcassonne answered 3/10, 2011 at 12:5 Comment(7)
document.getElementById should be sufficient and you do not need jQuery for it! ;-)Apocarp
Actually, according to the question, it was jQuery solution.Carcassonne
or even shorter one, $('#password')[0].type = 'text';Carcassonne
this can cause issues with IE9, type is undefined. Great for other browsers though.Oarsman
$('input.number_entry').each(function(){this.type = 'number';}); for all inputs with a given classFrants
IE 8 will actually throw an error if you try to change the type from "password" to "text" in this way. The error says "Could not get the type property. This command is not supported."Crossstitch
Fantastic it worksIrmgardirmina
S
76

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.

Stallings answered 21/2, 2010 at 0:51 Comment(4)
You can chain the following functions as well: $('#password').show(); $('#password').focus(); as $('#password').show().focus();Bottle
I have both fields together like this: <input type="text" /><input type="password" /> and I still get a vertical shift in IE (9) when they swap. Chaining the methods ($('#password').show().focus();) didn't help with that, but it was a fun optimization move. Overall this was the best solution.Corrigan
if the user move focus to another control and onblur fired the focus will go back to the fake password fieldCliffcliffes
You should use: if ($('#password').val() == '') { rather than: if ($('#password').attr('value') == '') { Otherwise the password value will always display 'password' onblur.Substrate
S
54

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.

Southeast answered 15/2, 2013 at 20:12 Comment(2)
A jsFiddle demo of placeholder="Password". The HTML spec and MDN on the placeholder attribute. A JavaScript shim for placeholder.Whichsoever
IE 8 is dead now. Long live native HTML solutions. Throw your placeholder shims away and celebrate.Southeast
G
13

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;
    }
}
Graviton answered 3/10, 2011 at 16:56 Comment(2)
That's just toooooo bad, if everyone says F... it, then nothing would work, it should work cross browser or not at all.Loftin
Speaking of gists... you should create one for this code. gist.github.comBeeline
H
9

This works for me.

$('#password').replaceWith($('#password').clone().attr('type', 'text'));
Halliday answered 27/6, 2012 at 1:58 Comment(2)
Thanks! This solves the issues I was having with the other answers not working in IE. Just remember this is a new object so you will have to re-grab it from the DOM if you have stored $('#password') in a variable.Oarsman
This does not work in IE8. You still get the "type property can't be changed" error.Stationer
H
7

This Worked for me.

$('#newpassword_field').attr("type", 'text');
Hunchbacked answered 8/12, 2017 at 5:52 Comment(0)
I
6

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!!! ;-)

Illfounded answered 18/1, 2010 at 6:22 Comment(0)
E
5

Have you tried using .prop()?

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

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

Expanse answered 15/1, 2014 at 7:35 Comment(1)
Works in Cordova 6 webviewArbitress
F
4

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?

Forgave answered 9/12, 2010 at 1:9 Comment(0)
H
3

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');
Howe answered 9/10, 2009 at 15:0 Comment(0)
C
3

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.

Carline answered 2/7, 2011 at 13:49 Comment(0)
S
3

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();
    }
});
Spectrometer answered 25/2, 2012 at 21:38 Comment(0)
R
2

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.

Radioactive answered 9/10, 2009 at 15:1 Comment(0)
V
2

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...

Villalpando answered 28/10, 2011 at 2:1 Comment(0)
P
2

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+'">');
}); 
Pebble answered 25/8, 2014 at 9:47 Comment(0)
R
2

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')
Ramayana answered 21/10, 2014 at 12:17 Comment(0)
J
1

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" />
Jacobine answered 11/3, 2011 at 10:29 Comment(0)
R
1
$('#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'>
Rabblement answered 3/9, 2011 at 14:57 Comment(0)
A
1

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!

Armelda answered 4/9, 2011 at 2:50 Comment(1)
Actually, forget that - just use delete jQuery.attrHooks.type to remove jQuery's special handling of input types.Armelda
Q
1
jQuery.fn.outerHTML = function() {
    return $(this).clone().wrap('<div>').parent().html();
};
$('input#password').replaceWith($('input.password').outerHTML().replace(/text/g,'password'));
Queenhood answered 12/10, 2011 at 11:29 Comment(0)
U
1

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/

Unlade answered 27/10, 2011 at 21:21 Comment(0)
P
1

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.

Palladin answered 13/2, 2012 at 17:26 Comment(0)
K
1

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>
Kirchner answered 24/12, 2016 at 13:11 Comment(0)
C
1

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://mcmap.net/q/75713/-jquery-ui-datepicker-not-working).

Castellated answered 18/4, 2020 at 21:12 Comment(0)
G
0

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();
     });
    }
  )});
Geber answered 22/8, 2011 at 8:30 Comment(1)
This does not work in IE8. You still get the "type property can't be changed" error.Stationer
I
0

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;
Isochronous answered 27/6, 2013 at 15:59 Comment(0)
O
0

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'));

Orellana answered 12/3, 2014 at 2:20 Comment(0)
G
0

This Worked for me.

<div class="ui icon input">
    <input type="password" id="password">
    <i class="eye slash link outline icon"></i>
</div>

JS

 $(".eye").click(function() {
  if ($('#password')[0].type === 'text') {
    $('#password')[0].type = 'password';
    $('.eye').addClass('slash');
  } else {
    $('#password')[0].type = 'text';
    $('.eye').removeClass('slash');
  }
});
Gearing answered 17/10, 2023 at 9:58 Comment(0)
I
-2

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
});
Ingrowing answered 19/4, 2018 at 4:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.