alterar o tipo de campo de entrada com jQuery


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

Isso deve alterar o #passwordcampo de entrada (com id="password") que é de type passwordum campo de texto normal e, em seguida, preencha o texto "Senha".

Mas não funciona. Por quê?

Aqui está o formulário:

<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 você quer mudar isso?
ChaosPandion 9/10/09

Desejo ter um texto de 'Senha' endereçado por um usuário na entrada para que os usuários saibam o que preencher (porque não há rótulo).
Richard Knop

Respostas:


258

É muito provável que essa ação seja evitada como parte do modelo de segurança do navegador.

Edit: na verdade, testando agora no Safari, recebo o erro type property cannot be changed .

Edit 2: isso parece ser um erro direto do jQuery. Usar o seguinte código DOM direto funciona bem:

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

Edit 3: Diretamente da fonte do jQuery, isso parece estar relacionado ao IE (e pode ser um bug ou parte de seu modelo de segurança, mas o jQuery não é 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
tenho que dizer, essa é a medida de segurança mais inútil que eu já vi. Não parece haver muita diferença entre alterar rapidamente o tipo de um campo e substituí-lo por um totalmente novo. Muito estranho ... de qualquer maneira, funcionou para mim. Obrigado!

2
não é de segurança material modelo, posso confirmar que ele não funciona no IE7, IE8 com o erro: Não foi possível obter a propriedade de tipo
Código Noviciado

Encontrei esta resposta em uma pesquisa e foi uma grande ajuda. No entanto, minha solução foi apenas remover essa verificação do jquery. Trabalhou muito bem.
Michael Michael

2
@ Michael, eu recomendaria contra alterar o jQuery diretamente. Além disso, cria uma responsabilidade de conflito no futuro, essa verificação provavelmente está em vigor por um motivo. Se você não precisar se preocupar com o suporte ao IE, poderá implementar uma extensão jQuery que é paralela, attrmas permite alterar o typeatributo nos inputelementos.
Eyelidlessness

1
Acabei de adicionar a atualização 4 - espero que ajude a explicar as coisas e como contorná-las.
precisa saber é o seguinte

76

Ainda mais fácil ... não há necessidade de toda a criação de elementos dinâmicos. Basta criar dois campos separados, tornando um o campo de senha 'real' (type = "password") e o campo de senha 'fake' (type = "text"), configurando o texto no campo falso para uma cor cinza claro e definindo o valor inicial para 'Senha'. Em seguida, adicione algumas linhas de Javascript com jQuery, como abaixo:

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

Portanto, quando o usuário digitar o campo de senha 'falso', ele será oculto, o campo real será mostrado e o foco será movido para o campo real. Eles nunca poderão inserir texto no campo falso.

Quando o usuário deixa o campo da senha real, o script verá se está vazio; nesse caso, ocultará o campo real e exibirá o falso.

Cuidado para não deixar espaço entre os dois elementos de entrada, pois o IE se posicionará um pouco após o outro (renderizando o espaço) e o campo parecerá se mover quando o usuário entrar / sair.


2
Você também pode encadear as seguintes funções: $('#password').show(); $('#password').focus();as$('#password').show().focus();
Anriëtte Myburgh

Eu tenho os dois campos juntos assim: <input type = "text" /> <input type = "password" /> e ainda recebo uma mudança vertical no IE (9) quando eles trocam. Encadear os métodos ($ ('# password'). Show (). Focus ();) não ajudou com isso, mas foi uma jogada divertida de otimização. No geral, essa foi a melhor solução.
AVProgrammer

se o foco movimento usuário para outro controle e onblur disparou o foco vai voltar para o campo de senha falsa
Allan Chua

Você deve usar: if ($ ('# password'). Val () == '') {em vez de: if ($ ('# password'). Attr ('value') == '') {Caso contrário, o O valor da senha sempre exibirá 'senha' no borrão.
Stephen Paul

75

Solução de uma etapa

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

5
document.getElementByIddeve ser suficiente e você não precisa do jQuery! ;-)
Gandaro

2
Na verdade, de acordo com a pergunta, era a solução jQuery.
Sanket Sahu

17
ou um mais curto, $ ('# password') [0] .type = 'text';
Sanket Sahu

2
isso pode causar problemas com o IE9, o tipo é indefinido. Ótimo para outros navegadores.
kravits88

1
O IE 8 realmente lançará um erro se você tentar alterar o tipo de "senha" para "texto" dessa maneira. O erro diz "Não foi possível obter a propriedade type. Este comando não é suportado."
allieferr

41

Hoje em dia, você pode simplesmente usar

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

Mas é claro, você realmente deveria fazer isso

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

em todos, exceto no IE. Existem espaços reservados para imitar essa funcionalidade no IE também.



1
O IE 8 está morto agora. Vida útil longa de soluções HTML nativas. Jogue seus espaços reservados e comemore.
Andrew

14

Uma solução mais entre navegadores ... Espero que a essência disso ajude alguém por aí.

Esta solução tenta definir o typeatributo e, se falhar, simplesmente cria um novo<input> elemento, preservando os atributos do elemento e os manipuladores 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;
    }
}

Isso é muito ruim, se todo mundo disser F ... isso, então nada funcionaria, deve funcionar em vários navegadores ou não.
Val

Falando em essência ... você deve criar uma para este código. gist.github.com
Christopher Parker

8

Isso funciona para mim.

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

Obrigado! Isso resolve os problemas que eu estava tendo com as outras respostas que não estavam funcionando no IE. Lembre-se de que este é um novo objeto, assim você terá que buscá-lo novamente no DOM se tiver armazenado $ ('# password') em uma variável.
kravits88

1
Isso não funciona no IE8. Você ainda recebe o erro "a propriedade do tipo não pode ser alterada".
Jcoffland

6

A melhor maneira de usar o jQuery:


Deixe o campo de entrada original oculto na tela.

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

Crie um novo campo de entrada em tempo real por JavaScript.

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

Migre o ID e o valor do campo de entrada oculto para o novo 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 contornar o erro no IE como type property cannot be changed , você pode achar isso útil da seguinte maneira:

Anexe um evento de clique / foco / alteração ao novo elemento de entrada, a fim de disparar o mesmo evento na entrada oculta.

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

O elemento de entrada oculto antigo ainda está dentro do DOM, portanto reagirá com o evento acionado pelo novo elemento de entrada. À medida que o ID é trocado, o novo elemento de entrada age como o antigo e responde a qualquer chamada de função ao ID da entrada oculta antiga, mas parece diferente.

Um pouco complicado, mas funciona !!! ;-)



4

Não testei no IE (já que eu precisava disso para um site para iPad) - um formulário que não podia alterar o HTML, mas poderia adicionar JS:

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

(JS da velha escola é feio ao lado de todo o jQuery!)

Mas, http://bugs.jquery.com/ticket/1957 vincula ao MSDN: "No Microsoft Internet Explorer 5, a propriedade type é de leitura / gravação uma vez, mas apenas quando um elemento de entrada é criado com o método createElement e antes de ser adicionado ao documento ". então talvez você possa duplicar o elemento, alterar o tipo, adicionar ao DOM e remover o antigo?


3

Basta criar um novo campo para ignorar essa coisa de segurança:

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

3

Recebi a mesma mensagem de erro ao tentar fazer isso no Firefox 5.

Eu o resolvi usando o código abaixo:

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

E para usá-lo, basta definir os atributos onFocus e onBlur dos seus campos para algo como o seguinte:

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

Eu também uso isso para um campo de nome de usuário, portanto, alterna um valor padrão. Basta definir o segundo parâmetro da função para '' quando você o chamar.

Além disso, pode ser interessante notar que o tipo padrão do meu campo de senha é realmente senha, apenas no caso de um usuário não ter o javascript ativado ou se algo der errado, dessa forma a senha ainda estará protegida.

A função $ (document) .ready é jQuery e carrega quando o documento termina de carregar. Isso muda o campo da senha para um campo de texto. Obviamente, você terá que alterar 'password_field_id' para o ID do seu campo de senha.

Sinta-se livre para usar e modificar o código!

Espero que isso ajude todos que tiveram o mesmo problema que eu :)

- CJ Kent

EDIT: Boa solução, mas não absoluta. Funciona no FF8 e IE8, mas não totalmente no Chrome (versão 16.0.912.75). O Chrome não exibe o texto da senha quando a página é carregada. Além disso - o FF exibirá sua senha quando o preenchimento automático estiver ativado.


3

Solução simples para todos aqueles que desejam a funcionalidade em todos os 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

Isso funcionou para mim.

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

2

As propriedades de tipo não podem ser alteradas. É necessário substituir ou sobrepor a entrada por uma entrada de texto e enviar o valor à entrada de senha no envio.


2

Eu acho que você poderia usar uma imagem de fundo que contenha a palavra "senha" e alterá-la novamente para uma imagem de fundo vazia .focus().

.blur() ----> imagem com "senha"

.focus() -----> imagem sem "senha"

Você também pode fazer isso com CSS e jQuery. Faça com que um campo de texto apareça exatamente no topo do campo de senha, hide () esteja em focus () e concentre-se no campo de senha ...


2

Experimente esta
demonstração aqui

$(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 muito mais fácil com isso:

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

e para voltar ao campo de senha novamente ( assumindo que o campo de senha seja a segunda tag de entrada com tipo de texto ):

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

1

use este aqui é muito 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

Isto irá fazer o truque. Embora possa ser melhorado ignorar atributos que agora são irrelevantes.

Plugar:

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

Violino:

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


1

Simplesmente isso:

this.type = 'password';

tal como

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

Isso pressupõe que seu campo de entrada tenha sido definido como "texto" antes da mão.


1

Aqui está um pequeno trecho que permite alterar os typeelementos nos 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;
    }
}

Ele soluciona o problema removendo inputo documento, alterando otype e colocando-o de volta onde estava originalmente.

Observe que esse trecho foi testado apenas para navegadores WebKit - não há garantias para mais nada!


Na verdade, esqueça isso - basta usar delete jQuery.attrHooks.typepara remover o tratamento especial do jQuery dos tipos de entrada.
jb.

1

Aqui está um método que usa uma imagem ao lado do campo de senha para alternar entre ver a senha (entrada de texto) e não vê-la (entrada de senha). Uso uma imagem de "olho aberto" e "olho fechado", mas você pode usar o que mais lhe convier. O modo como funciona é ter duas entradas / imagens e, ao clicar na imagem, o valor é copiado da entrada visível para a oculta e, em seguida, sua visibilidade é trocada. Ao contrário de muitas das outras respostas que usam nomes codificados, essa é geral o suficiente para ser usada várias vezes em uma página. Também degrada normalmente se o JavaScript estiver indisponível.

Aqui está a aparência de dois deles em uma página. Neste exemplo, a Senha-A foi revelada clicando no olho.

Como fica

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

Eu gosto dessa maneira, para alterar o tipo de um elemento de entrada: old_input.clone () .... Aqui está um exemplo. Há uma caixa de seleção "id_select_multiple". Se isso for alterado para "selecionado", os elementos de entrada com o nome "foo" deverão ser alterados para caixas de seleção. Se não estiver marcado, eles devem se tornar botões de opção novamente.

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

Isso não funciona no IE8. Você ainda recebe o erro "a propriedade do tipo não pode ser alterada".
Jcoffland

0

aqui está uma solução 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

Eu criei uma extensão jQuery para alternar entre texto e senha. Funciona no IE8 (provavelmente 6 e 7 também, mas não foi testado) e não perderá seu valor ou 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 como um encanto. Você pode simplesmente ligar $('#element').togglePassword();para alternar entre os dois ou dar uma opção para 'forçar' a ação com base em outra coisa (como uma caixa de seleção):$('#element').togglePassword($checkbox.prop('checked'));


0

Apenas mais uma opção para todos os amantes do IE8, e funciona perfeitamente em navegadores mais recentes. Você pode apenas colorir o texto para corresponder ao fundo da entrada. Se você tiver um único campo, isso mudará a cor para preto quando você clicar / focalizar o campo. Eu não usaria isso em um site público, pois isso 'confundiria' a maioria das pessoas, mas estou usando-o em uma seção ADMIN, na qual apenas uma pessoa tem acesso às senhas dos usuários.

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

-OU-

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

Isso, também necessário, mudará o texto de volta para branco quando você sair do campo. Simples, simples, simples.

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

[Outra opção] Agora, se você tiver vários campos que estiver procurando, todos com o mesmo ID, como eu estou usando, adicione uma classe de 'passe' aos campos nos quais deseja ocultar o texto. Defina campos de senha, digite "texto". Dessa forma, apenas os campos com uma classe de 'passe' serão alterados.

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

Aqui está a segunda parte disso. Isso muda o texto novamente para branco depois que você sai do campo.

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

0

Eu apenas fiz o seguinte para alterar o tipo de uma entrada:

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

e funciona.

Eu estava precisando fazer isso porque estava usando os datepickers da UI do jQuery em um projeto do ASP NET Core 3.1 e eles não estavam funcionando corretamente em navegadores baseados no Chromium (consulte: https://stackoverflow.com/a/61296225/7420301 ).

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.