change type of input field with jQuery

2018-12-31 06:35发布

$(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>

28条回答
君临天下
2楼-- · 2018-12-31 06:59

This Worked for me.

$('#newpassword_field').attr("type", 'text');
查看更多
刘海飞了
3楼-- · 2018-12-31 07:00

One step solution

$('#password').get(0).type = 'text';
查看更多
初与友歌
4楼-- · 2018-12-31 07:01

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;
查看更多
人间绝色
5楼-- · 2018-12-31 07:02

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

查看更多
心情的温度
6楼-- · 2018-12-31 07:03

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";
查看更多
余欢
7楼-- · 2018-12-31 07:03

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

查看更多
登录 后发表回答