cambiar el tipo de campo de entrada con jQuery


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

Se supone que esto cambia el #passwordcampo de entrada (con id="password") que es de type passwordun campo de texto normal, y luego completa el texto "Contraseña".

Sin embargo, no funciona. ¿Por qué?

Aquí está la forma:

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

por que lo quieres cambiar?
ChaosPandion

Quiero tener un texto de 'Contraseña' amigable para el usuario en la entrada para que los usuarios sepan qué completar (porque no hay etiqueta).
Richard Knop

Respuestas:


258

Es muy probable que esta acción se evite como parte del modelo de seguridad del navegador.

Editar: de hecho, probando ahora en Safari, me sale el error type property cannot be changed.

Edición 2: eso parece ser un error directamente de jQuery. Usar el siguiente código DOM directo funciona bien:

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

Edición 3: Directamente desde la fuente jQuery, esto parece estar relacionado con IE (y podría ser un error o parte de su modelo de seguridad, pero jQuery no es específico):

// 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";

12
Debo decir que esta es la medida de seguridad más inútil que he visto. No parece haber mucha diferencia entre cambiar rápidamente el tipo de campo y reemplazarlo por uno totalmente nuevo. Muy extraño ... de todos modos, funcionó para mí. ¡Gracias!

2
que no es de seguridad modelo de cosas, puedo confirmar que no funciona en IE7, IE8 con el error: No se pudo obtener la propiedad type
Código Noviciado

Encontré esta respuesta en una búsqueda y fue de gran ayuda. Sin embargo, mi solución fue simplemente eliminar ese cheque de jquery. Funcionó muy bien.
Michael

2
@ Michael, recomendaría no modificar jQuery directamente. Además de que crea una responsabilidad de conflicto en el futuro, esa verificación probablemente esté en su lugar por una razón. Si no necesita preocuparse por el soporte de IE, podría implementar una extensión jQuery que sea paralela attrpero que permita cambiar el typeatributo en los inputelementos.
párpado

1
Acabo de agregar la actualización 4: espero que ayude a explicar las cosas y cómo solucionarlas.
ClarkeyBoy

76

Aún más fácil ... no hay necesidad de crear todo el elemento dinámico. Simplemente cree dos campos separados, convirtiendo uno en el campo de contraseña 'real' (tipo = "contraseña") y otro en un campo de contraseña 'falso' (tipo = "texto"), estableciendo el texto en el campo falso en un color gris claro y configurando el valor inicial a 'Contraseña'. Luego agregue algunas líneas de Javascript con jQuery como se muestra a continuación:

    <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()" />

Entonces, cuando el usuario ingresa al campo de contraseña 'falsa', estará oculto, se mostrará el campo real y el foco se moverá al campo real. Nunca podrán ingresar texto en el campo falso.

Cuando el usuario abandona el campo de contraseña real, el script verá si está vacío y, de ser así, ocultará el campo real y mostrará el falso.

Tenga cuidado de no dejar un espacio entre los dos elementos de entrada porque IE colocará uno un poco después del otro (renderizando el espacio) y el campo parecerá moverse cuando el usuario lo ingrese / salga.


2
También puede encadenar las siguientes funciones: $('#password').show(); $('#password').focus();como$('#password').show().focus();
Anriëtte Myburgh

Tengo ambos campos juntos de la siguiente manera: <input type = "text" /> <input type = "password" /> y todavía obtengo un desplazamiento vertical en IE (9) cuando se intercambian. Encadenar los métodos ($ ('# contraseña'). Show (). Focus ();) no ayudó con eso, pero fue un movimiento de optimización divertido. En general, esta fue la mejor solución.
AVProgrammer

si el usuario mueve el foco a otro control y onblur dispara, el foco volverá al campo de contraseña falsa
Allan Chua

Debe usar: if ($ ('# contraseña'). Val () == '') {en lugar de: if ($ ('# contraseña'). Attr ('value') == '') {De lo contrario, el el valor de la contraseña siempre mostrará 'contraseña' onblur.
Stephen Paul

75

Solución de un paso

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

55
document.getElementById¡debería ser suficiente y no necesita jQuery para ello! ;-)
Gandaro

2
En realidad, según la pregunta, era la solución jQuery.
Sanket Sahu

17
o incluso uno más corto, $ ('# contraseña') [0] .type = 'texto';
Sanket Sahu

2
Esto puede causar problemas con IE9, el tipo no está definido. Sin embargo, es genial para otros navegadores.
kravits88

1
IE 8 en realidad arrojará un error si intenta cambiar el tipo de "contraseña" a "texto" de esta manera. El error dice "No se pudo obtener la propiedad type. Este comando no es compatible".
allieferr

41

Hoy en día, solo puedes usar

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

Pero, por supuesto, deberías hacer esto

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

en todos menos en IE. Hay marcadores de posición para imitar esa funcionalidad en IE también.



1
IE 8 está muerto ahora. Larga vida a las soluciones HTML nativas. Tire a la basura su marcador de posición y celebre.
Andrew

14

Una solución más entre navegadores ... Espero que la esencia de esto ayude a alguien por ahí.

Esta solución intenta establecer el typeatributo, y si falla, simplemente crea un nuevo <input>elemento, preservando los atributos del elemento y los controladores de eventos.

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;
    }
}

Eso es demasiado malo, si todos dicen F ... eso, entonces nada funcionaría, debería funcionar en todos los navegadores o no funcionaría.
Val

Hablando de lo esencial ... deberías crear uno para este código. gist.github.com
Christopher Parker

8

Esto funciona para mi.

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

¡Gracias! Esto resuelve los problemas que tenía con las otras respuestas que no funcionaban en IE. Solo recuerde que este es un objeto nuevo, por lo que tendrá que volver a tomarlo del DOM si ha almacenado $ ('# contraseña') en una variable.
kravits88

1
Esto no funciona en IE8. Aún recibe el error "no se puede cambiar la propiedad de tipo".
jcoffland

6

Una forma definitiva de usar jQuery:


Deje el campo de entrada original oculto de la pantalla.

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

Cree un nuevo campo de entrada sobre la marcha mediante JavaScript.

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

Migre la ID y el valor del campo de entrada oculto al nuevo campo de entrada.

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

Para evitar el error en IE como type property cannot be changed , puede encontrar esto útil de la siguiente manera:

Adjunte evento click / focus / change al nuevo elemento de entrada, para activar el mismo evento en la entrada oculta.

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

El antiguo elemento de entrada oculto todavía está dentro del DOM, por lo que reaccionará con el evento desencadenado por el nuevo elemento de entrada. A medida que se intercambia la ID, el nuevo elemento de entrada actuará como el anterior y responderá a cualquier llamada de función a la ID de la entrada oculta anterior, pero se verá diferente.

Un poco complicado pero funciona! ;-)



4

No he probado en IE (ya que necesitaba esto para un sitio de iPad), un formulario que no podía cambiar el HTML pero podía agregar JS:

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

(¡Old School JS es feo al lado de todos los jQuery!)

Pero, http://bugs.jquery.com/ticket/1957 enlaza con MSDN: "A partir de Microsoft Internet Explorer 5, la propiedad type es read / write-once, pero solo cuando se crea un elemento de entrada con el método createElement y antes de que se agregue al documento ". Entonces, ¿tal vez podría duplicar el elemento, cambiar el tipo, agregar al DOM y eliminar el antiguo?


3

Simplemente cree un nuevo campo para evitar esta cosa de seguridad:

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

3

Recibí el mismo mensaje de error al intentar hacer esto en Firefox 5.

Lo resolví usando el siguiente código:

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

Y para usarlo, simplemente configure los atributos onFocus y onBlur de sus campos en algo como lo siguiente:

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

Lo uso también para un campo de nombre de usuario, por lo que alterna un valor predeterminado. Simplemente establezca el segundo parámetro de la función en '' cuando lo llame.

También vale la pena señalar que el tipo predeterminado de mi campo de contraseña es en realidad contraseña, en caso de que un usuario no tenga habilitado JavaScript o si algo sale mal, de esa manera su contraseña aún está protegida.

La función $ (document) .ready es jQuery y se carga cuando el documento ha terminado de cargarse. Esto luego cambia el campo de contraseña a un campo de texto. Obviamente, tendrá que cambiar 'password_field_id' a la identificación de su campo de contraseña.

¡Siéntase libre de usar y modificar el código!

Espero que esto ayude a todos los que tuvieron el mismo problema que yo :)

- CJ Kent

EDITAR: Buena solución pero no absoluta. Funciona en FF8 e IE8 PERO no completamente en Chrome (16.0.912.75 ver). Chrome no muestra el texto de la contraseña cuando se carga la página. Además, FF mostrará su contraseña cuando la función de autocompletar esté activada.


3

Solución simple para todos aquellos que desean la funcionalidad en todos los navegadores:

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();
    }
});

3

Esto funcionó para mí.

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

2

Las propiedades de tipo no se pueden cambiar, debe reemplazar o superponer la entrada con una entrada de texto y enviar el valor a la entrada de contraseña al enviar.


2

Supongo que podría usar una imagen de fondo que contenga la palabra "contraseña" y volver a cambiarla a una imagen de fondo vacía en .focus() .

.blur() ----> imagen con "contraseña"

.focus() -----> imagen sin "contraseña"

También puedes hacerlo con algunos CSS y jQuery. Haga que un campo de texto aparezca exactamente encima del campo de contraseña, hide () está en foco () y enfóquese en el campo de contraseña ...


2

Prueba esta
demo está aquí

$(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+'">');
}); 

2

Funciona mucho más fácil con eso:

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

y para volver al campo de contraseña nuevamente, ( suponiendo que el campo de contraseña es la segunda etiqueta de entrada con tipo de texto ):

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

1

usa este es muy fácil

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

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

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

1

Esto hará el truco. Aunque podría mejorarse para ignorar los atributos que ahora son irrelevantes.

Enchufar:

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

Uso:

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

Violín:

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


1

Simplemente esto:

this.type = 'password';

como

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

Esto supone que su campo de entrada se configuró en "texto" de antemano.


1

Aquí hay un pequeño fragmento que le permite cambiar los typeelementos de los documentos.

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;
    }
}

Se soluciona el problema eliminando el inputdel documento, cambiando eltype y volviendo a colocarlo donde estaba originalmente.

Tenga en cuenta que este fragmento solo se probó para los navegadores WebKit, ¡sin garantías de nada más!


En realidad, olvídalo, solo úsalo delete jQuery.attrHooks.typepara eliminar el manejo especial de jQuery de los tipos de entrada.
jb.

1

Aquí hay un método que usa una imagen al lado del campo de contraseña para alternar entre ver la contraseña (ingreso de texto) y no verla (ingreso de contraseña). Uso una imagen de "ojo abierto" y "ojo cerrado", pero puedes usar lo que te convenga. La forma en que funciona es tener dos entradas / imágenes y al hacer clic en la imagen, el valor se copia de la entrada visible a la oculta, y luego se intercambia su visibilidad. A diferencia de muchas de las otras respuestas que usan nombres codificados, esta es lo suficientemente general como para usarla varias veces en una página. También se degrada con gracia si JavaScript no está disponible.

Así es como se ven dos de estos en una página. En este ejemplo, la contraseña A se ha revelado haciendo clic en su ojo.

Como luce

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


0

Me gusta de esta manera, cambiar el tipo de un elemento de entrada: old_input.clone () .... Aquí hay un ejemplo. Hay una casilla de verificación "id_select_multiple". Si esto se cambia a "seleccionado", los elementos de entrada con el nombre "foo" se deben cambiar a casillas de verificación. Si no se marca, deberían volver a ser botones de radio.

  $(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();
     });
    }
  )});

Esto no funciona en IE8. Aún recibe el error "no se puede cambiar la propiedad de tipo".
jcoffland

0

Heres una solución DOM

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;

0

He creado una extensión jQuery para alternar entre texto y contraseña. Funciona en IE8 (probablemente 6 y 7 también, pero no probado) y no perderá su valor o atributos:

$.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);
        }
    });
};

Funciona de maravilla. Simplemente puede llamar $('#element').togglePassword();para cambiar entre los dos o dar una opción para 'forzar' la acción basada en otra cosa (como una casilla de verificación):$('#element').togglePassword($checkbox.prop('checked'));


0

Solo otra opción para todos los amantes de IE8, y funciona perfecto en los navegadores más nuevos. Simplemente puede colorear el texto para que coincida con el fondo de la entrada. Si tiene un solo campo, esto cambiará el color a negro cuando haga clic / enfoque en el campo. No usaría esto en un sitio público ya que 'confundiría' a la mayoría de las personas, pero lo estoy usando en una sección de ADMINISTRACIÓN donde solo una persona tiene acceso a las contraseñas de los usuarios.

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

-O-

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

Esto, también necesario, cambiará el texto a blanco cuando abandone el campo. Simple, simple, simple.

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

[Otra opción] Ahora, si tiene varios campos que está buscando, todos con el mismo ID, para el que lo estoy usando, agregue una clase de 'pasar' a los campos en los que desea ocultar el texto. Configure el los campos de contraseña escriben en 'texto'. De esta manera, solo se cambiarán los campos con una clase de 'pase'.

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

Aquí está la segunda parte de esto. Esto cambia el texto de nuevo a blanco después de abandonar el campo.

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

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.