web-dev-qa-db-fra.com

changer le type de champ de saisie avec jQuery

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

Ceci est supposé changer le champ de saisie #password (avec id="password") qui est de typepassword en un champ de texte normal, puis remplissez le texte "Mot de passe".

Cela ne fonctionne pas, cependant. Pourquoi?

Voici le formulaire:

<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>
200
Richard Knop

Il est très probable que cette action soit empêchée dans le cadre du modèle de sécurité du navigateur.

Edit: en effet, en testant maintenant dans Safari, je reçois l’erreur type property cannot be changed.

Edit 2: cela semble être une erreur tout droit sortie de jQuery. L'utilisation du code DOM suivant fonctionne parfaitement:

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

Edit 3: directement à partir de la source jQuery, cela semble être lié à IE (et pourrait être un bogue ou une partie de leur modèle de sécurité, mais jQuery n’est pas spécifique):

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

Encore plus facilement ... il n’est pas nécessaire de créer tous les éléments dynamiques. Il suffit de créer deux champs distincts, en faisant l’un des champs "réel" (type = "mot de passe") et un "faux" mot de passe (type = "texte"), définissant le texte du faux champ sur une couleur gris clair et définir la valeur initiale sur 'Mot de passe'. Ajoutez ensuite quelques lignes de Javascript avec jQuery comme ci-dessous:

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

Ainsi, lorsque l'utilisateur saisit le faux mot de passe, celui-ci est masqué, le vrai champ est affiché et le focus est déplacé sur le vrai. Ils ne pourront jamais entrer du texte dans le faux champ.

Lorsque l'utilisateur quitte le champ du mot de passe réel, le script verra s'il est vide et, le cas échéant, masquera le champ réel et affichera le faux.

Veillez à ne pas laisser d'espace entre les deux éléments en entrée car IE en positionnera l'un après l'autre (restitution de l'espace) et le champ semblera bouger lorsque l'utilisateur le saisira/le quittera.

76
Joe

Solution en une étape

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

De nos jours, vous pouvez simplement utiliser

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

Mais bien sûr, vous devriez vraiment faire ça

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

dans tout sauf IE. Il existe également des substituts pour imiter cette fonctionnalité dans IE.

38
Andrew

Une solution plus multi-navigateur… J'espère que l'essentiel de ceci aidera quelqu'un.

Cette solution tente de définir l'attribut type. En cas d'échec, elle crée simplement un nouvel élément <input>, en préservant les attributs de l'élément et les gestionnaires d'événements.

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

Cela fonctionne pour moi.

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

Un moyen ultime d'utiliser jQuery:


Laissez le champ de saisie d'origine masqué à l'écran.

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

Créez un nouveau champ de saisie à la volée avec JavaScript.

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

Migrez l'ID et la valeur du champ de saisie masqué vers le nouveau champ de saisie.

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

Pour contourner l'erreur sur IE comme type property cannot be changed, vous pouvez trouver ceci utile comme suit:

Attachez l'événement clic/focus/change au nouvel élément d'entrée afin de déclencher le même événement sur une entrée masquée.

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

L'ancien élément d'entrée masqué est toujours dans le DOM; il réagira donc avec l'événement déclenché par le nouvel élément d'entrée. Lorsque l'ID est échangé, le nouvel élément d'entrée agit comme l'ancien et répond à tout appel de fonction à l'ID de l'ancienne entrée masqué, mais son apparence est différente.

Un peu délicat mais ça marche !!! ;-)

6
Ken Pega

Avez-vous essayé d'utiliser .prop ()?

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

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

4
Mark Mckelvie

Je n'ai pas testé dans IE (car j'avais besoin de cela pour un site iPad) - un formulaire pour lequel je ne pouvais pas modifier le code HTML, mais je pouvais ajouter JS:

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

(Old school JS est laide à côté de tous les jQuery!)

Mais, http://bugs.jquery.com/ticket/1957 renvoie à MSDN: "À partir de Microsoft Internet Explorer 5, la propriété type est en lecture/écriture une seule fois, mais uniquement lorsqu'un élément d'entrée est créé avec la méthode createElement et avant de l'ajouter au document. " alors peut-être pourriez-vous dupliquer l'élément, changer le type, ajouter à DOM et supprimer l'ancien?

4
hood

Solution simple pour tous ceux qui veulent la fonctionnalité dans tous les navigateurs:

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
hohner

Créez simplement un nouveau champ pour contourner ce problème de sécurité:

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

J'ai reçu le même message d'erreur lorsque j'essayais de le faire dans Firefox 5.

Je l'ai résolu en utilisant le code ci-dessous:

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

Et pour l'utiliser, il suffit de définir les attributs onFocus et onBlur de vos champs comme suit:

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

J'utilise cela aussi pour un champ de nom d'utilisateur, donc il bascule une valeur par défaut. Réglez simplement le deuxième paramètre de la fonction sur '' lorsque vous l'appelez.

Il est également intéressant de noter que le champ par défaut de mon mot de passe est en fait un mot de passe, juste au cas où un utilisateur n'activerait pas le javascript ou en cas de problème, son mot de passe est toujours protégé.

La fonction $ (document) .ready est jQuery et se charge lorsque le chargement du document est terminé. Cela change ensuite le champ mot de passe en un champ texte. Évidemment, vous devrez remplacer "password_field_id" par l'identifiant de votre champ de mot de passe.

N'hésitez pas à utiliser et à modifier le code!

J'espère que cela aide tous ceux qui ont eu le même problème que moi :)

- CJ Kent

EDIT: bonne solution mais pas absolue. Fonctionne sur FF8 et IE8 MAIS pas complètement sur Chrome (version 16.0.912.75). Chrome n'affiche pas le texte mot de passe lors du chargement de la page. De plus, FF affichera votre mot de passe lorsque le remplissage automatique est activé.

3
cjk84

Cela fonctionne beaucoup plus facilement avec ça:

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

et pour le remettre à nouveau dans le champ mot de passe, (en supposant que le champ mot de passe est la deuxième balise d'entrée avec le type de texte):

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

Cela a fonctionné pour moi.

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

Les propriétés de type ne peuvent pas être modifiées. Vous devez remplacer ou superposer l'entrée par une entrée de texte et envoyer la valeur à l'entrée de mot de passe lors de l'envoi.

2
Jesse Kochis

Je suppose que vous pouvez utiliser une image d’arrière-plan contenant le mot "mot de passe" et la redéfinir en une image d’arrière-plan vide sur .focus().

.blur() ----> image avec "mot de passe"

.focus() -----> image sans "mot de passe"

Vous pouvez également le faire avec certains CSS et jQuery. Avoir un champ de texte apparaissant exactement au-dessus du champ de mot de passe, hide () est sur le focus () et se concentrer sur le champ de mot de passe ...

2
rhodium

Essaye ça
la démo est ici

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

Voici une méthode qui utilise une image en regard du champ de mot de passe pour basculer entre afficher le mot de passe (saisie de texte) et ne pas le voir (saisie de mot de passe). J'utilise une image "yeux ouverts" et "yeux fermés", mais vous pouvez utiliser ce que vous voulez. La façon dont cela fonctionne est d'avoir deux entrées/images et en cliquant sur l'image, la valeur est copiée de l'entrée visible vers l'entrée cachée, puis leur visibilité est échangée. Contrairement à beaucoup d'autres réponses qui utilisent des noms codés en dur, celle-ci est suffisamment générale pour pouvoir être utilisée plusieurs fois sur une page. Il se dégrade également gracieusement si JavaScript n'est pas disponible.

Voici à quoi ressemblent deux de ces éléments sur une page. Dans cet exemple, le mot de passe-A a été révélé en cliquant sur son œil.

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>
1
John Hascall

Simplement ceci:

this.type = 'password';

tel que

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

Cela suppose que votre champ de saisie a été défini sur "texte" avant de commencer.

1
Michael

Voici un petit extrait qui vous permet de changer la type des éléments dans les 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;
    }
}

Il résout le problème en supprimant la input du document, en modifiant la type, puis en le remettant à l’origine.

Notez que cet extrait n'a été testé que pour les navigateurs WebKit - aucune garantie sur rien d'autre!

1
jb.

Ça fera l'affaire. Bien qu’il puisse être amélioré d’ignorer les attributs qui ne sont plus pertinents.

Brancher:

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

Violon:

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

1
joshcomley
$('#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
vankaiser

utiliser celui-ci c'est très facile

<input id="pw" onclick="document.getElementById('pw').type='password';
  document.getElementById('pw').value='';"
  name="password" type="text" value="Password" />
1
Farhan
jQuery.fn.outerHTML = function() {
    return $(this).clone().wrap('<div>').parent().html();
};
$('input#password').replaceWith($('input.password').outerHTML().replace(/text/g,'password'));
1
UnLoCo

Juste une autre option pour tous les amateurs d'IE8, et cela fonctionne parfaitement dans les nouveaux navigateurs. Vous pouvez simplement colorer le texte pour qu'il corresponde à l'arrière-plan de l'entrée. Si vous avez un seul champ, cela changera la couleur en noir lorsque vous cliquez/faites la mise au point sur le champ. Je ne l'utiliserais pas sur un site public, car cela "embrouillerait" la plupart des gens, mais je l'utilise dans une section ADMIN où une seule personne a accès aux mots de passe des utilisateurs.

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

-OU-

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

Ceci, également nécessaire, changera le texte en blanc lorsque vous quitterez le champ. Simple, simple, simple.

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

[Une autre option] Maintenant, si vous recherchez plusieurs champs à vérifier, tous avec le même identifiant, comme je l’utilise pour le moment, ajoutez une classe de 'pass' aux champs dans lesquels vous souhaitez masquer le texte. les champs de mot de passe tapez 'text'. De cette façon, seuls les champs avec une classe de 'pass' seront modifiés.

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

Voici la deuxième partie de ceci. Cela change le texte en blanc après que vous ayez quitté le champ.

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

heres une solution 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
chiliNUT

J'aime cette façon, pour changer le type d'un élément input: old_input.clone () .... Voici un exemple. Il y a une case à cocher "id_select_multiple". Si cette option est remplacée par "sélectionnée", les éléments d'entrée portant le nom "foo" doivent être remplacés par des cases à cocher. Si cette case n'est pas cochée, ils doivent redevenir des boutons 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();
     });
    }
  )});
0
guettli

J'ai créé une extension jQuery permettant d'alterner texte et mot de passe. Fonctionne dans IE8 (probablement 6 et 7 également, mais pas testé) et ne perdra pas votre valeur ou vos attributs:

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

Fonctionne comme un charme. Vous pouvez simplement appeler $('#element').togglePassword(); pour basculer entre les deux ou donner la possibilité de "forcer" l'action en fonction de quelque chose d'autre (comme une case à cocher): $('#element').togglePassword($checkbox.prop('checked'));

0
J_A_X