changer le type de champ d'entrée avec jQuery
$(document).ready(function() {
// #login-box password field
$('#password').attr('type', 'text');
$('#password').val('Password');
});
ceci est supposé changer le champ d'entrée #password
(avec id="password"
) qui est de type
password
à un champ de texte normal, puis remplir le texte"Mot de passe".
ça ne marche pas. 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>
28 réponses
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, les tests actuellement dans Safari, j'obtiens l'erreur type property cannot be changed
.
Edit 2: Cela semble être une erreur tout droit sortie de jQuery. Utiliser le code DOM droit suivant fonctionne très bien:
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 soit un bug 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";
encore plus facile... il n'y a pas besoin de créer tous les éléments dynamiques. Il suffit de créer deux champs séparés, en faisant l'un le champ"vrai" mot de passe (type="mot de passe") et l'autre un champ "faux" mot de Passe (type= "Texte"), en définissant le texte dans le champ "faux" à une couleur grise claire et en définissant la valeur initiale à "mot de passe". Ajoutez ensuite quelques lignes de Javascript avec jQuery comme suit:
<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 entre dans le "faux" champ mot de passe, il sera caché, le vrai champ sera affiché, et l'accent sera mis sur le vrai champ. Ils ne pourront jamais entrer de texte dans le faux champ.
lorsque l'utilisateur quitte le champ de mot de passe réel, le script verra s'il est vide, et si c'est le cas, il masquera le vrai champ et affichera le faux.
veillez à ne pas laisser d'espace entre les deux éléments d'entrée car IE positionnera L'un un peu après l'autre (rendant l'espace) et le champ semblera se déplacer lorsque le l'utilisateur entre et qui sort.
de nos jours, vous pouvez juste utiliser
$("#password").prop("type", "text");
mais bien sûr, vous devriez vraiment faire ça
<input type="password" placeholder="Password" />
en tout sauf IE. Il y a des shims placeholder là-bas pour imiter cette fonctionnalité dans IE aussi bien.
une solution plus cross-browser... j'espère que l'essentiel de cette aide quelqu'un là-bas.
cette solution essaie de définir l'attribut type
, et s'il échoue, il crée simplement un nouvel élément <input>
, 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;
}
}
ça me va.
$('#password').replaceWith($('#password').clone().attr('type', 'text'));
une façon ultime d'utiliser jQuery:
laissez le champ d'entrée original caché de 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éer un nouveau champ d'entrée à la volée par JavaScript.
var new_input = document.createElement("input");
migrer L'ID et la valeur du champ d'entrée caché vers le nouveau champ d'entrée.
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 cela utile comme belows:
attacher l'événement click/focus/change au nouvel élément input, afin de déclencher le même événement sur input caché.
$(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 caché est toujours à l'intérieur du DOM de sorte qu'il réagit 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 agira comme l'ancien et répondra à n'importe quel appel de fonction à L'ID de l'ancienne entrée cachée, mais paraîtra différent.
un peu délicat mais ça marche!!! ;-)
Je n'ai pas testé dans IE (puisque j'en avais besoin pour un site iPad) - un formulaire que je ne pouvais pas changer le HTML mais que je pouvais ajouter JS:
document.getElementById('phonenumber').type = 'tel';
(de la Vieille école JS est laid à côté de tous les jQuery!)
Mais, http://bugs.jquery.com/ticket/1957 liens vers MSDN: "Comme Microsoft Internet Explorer 5, le type de la propriété est en lecture/écriture-une fois, mais seulement lorsqu'un élément est créé avec la méthode createElement et avant qu'il soit ajoutée au document."donc, vous pourriez peut-être dupliquer l'élément, changer le type, ajouter à DOM et supprimer l'ancien?
Avez-vous essayé d'utiliser .prop()?
$("#password").prop('type','text');
il suffit de créer un nouveau champ pour contourner cette chose de sécurité:
var $oldPassword = $("#password");
var $newPassword = $("<input type='text' />")
.val($oldPassword.val())
.appendTo($oldPassword.parent());
$oldPassword.remove();
$newPassword.attr('id','password');
j'ai reçu le même message d'erreur en essayant 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, définissez les attributs onFocus et onBlur de vos champs à quelque chose comme ceci:
<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 ceci pour un champ de nom d'utilisateur aussi bien, donc il bascule une valeur par défaut. Il suffit de régler le deuxième paramètre de la fonction " quand vous l'appelez.
aussi, il pourrait être intéressant de noter que le type par défaut de mon champ Mot de passe est en fait mot de passe, juste au cas où un utilisateur n'a pas javascript activé ou si quelque chose tourne mal, de cette façon leur mot de passe est toujours protégé.
Le $(document).la fonction ready est jQuery, et charge lorsque le document a terminé le chargement. Cela change ensuite le champ Mot de passe en champ texte. Évidemment, vous devrez changer 'password_field_id' à l'id de votre champ password.
N'hésitez pas à utiliser et modifier le code!
Espérons que cela aide tout le monde qui avait le même problème, je l'ai fait :)
-- CJ Kent
EDIT: Bonne solution, mais pas absolue. Fonctionne sur FF8 et IE8 mais pas entièrement sur Chrome (16.0.912.75 ver). Chrome n'affiche pas le mot de passe texte lorsque la page se charge. Aussi-FF affichera votre mot de passe quand autofill est activé.
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();
}
});
ne peuvent pas être changées vous devez remplacer ou superposer l'entrée avec une entrée de texte et envoyer la valeur à l'entrée de mot de passe sur soumettre.
je suppose que vous pouvez utiliser une image de fond qui contient le mot" mot de passe "et la changer de nouveau à une image de fond vide sur .focus()
.
.blur()
----> image avec "mot de passe"
.focus()
-----> image sans "mot de passe"
vous pouvez aussi le faire avec quelques CSS et jQuery. Faites apparaître un champ texte exactement au-dessus du champ password, hide() est sur focus() et focus sur le champ password...
essayez ceci
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+'">');
});
ça a marché pour moi.
$('#newpassword_field').attr("type", 'text');
utilisez celui-ci, il est très facile
<input id="pw" onclick="document.getElementById('pw').type='password';
document.getElementById('pw').value='';"
name="password" type="text" value="Password" />
$('#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'>
jQuery.fn.outerHTML = function() {
return $(this).clone().wrap('<div>').parent().html();
};
$('input#password').replaceWith($('input.password').outerHTML().replace(/text/g,'password'));
ça fera l'affaire. Bien qu'il pourrait être amélioré pour ignorer les attributs qui sont plus pertinents.
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);
Utilisation:
$(":submit").changeType("checkbox");
violon:
simplement ceci:
this.type = 'password';
tel que
$("#password").click(function(){
this.type = 'password';
});
ceci suppose que votre champ d'entrée a été défini à" text " avant main.
voici un petit extrait qui vous permet de changer le 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 contourne le problème en enlevant le input
du document, en changeant le type
et en le remettant ensuite là où il était à l'origine.
notez que cet extrait n'a été testé que pour les navigateurs WebKit – aucune garantie sur quoi que ce soit d'autre!
il fonctionne beaucoup plus facile avec cela:
document.querySelector('input[type=password]').setAttribute('type', 'text');
et afin de le retourner à nouveau au champ Mot de passe, ( en supposant que le champ Mot de passe est la deuxième étiquette d'entrée avec le type de texte ):
document.querySelectorAll('input[type=text]')[1].setAttribute('type', 'password')
Voici une méthode qui utilise une image à côté du champ password pour basculer entre voir le mot de passe (entrée de texte) et ne pas le voir (Entrée de mot de passe). J'utilise une image" oeil ouvert "et" oeil fermé", mais vous pouvez utiliser ce qui vous convient. La façon dont il fonctionne est d'avoir deux entrées / images et en cliquant sur l'image, la valeur est copiée à partir de l'entrée visible à la cachée, puis leur visibilité est échangée. Contrairement à beaucoup d'autres réponses qui utilisent des noms codés en dur, celui-ci est assez générale pour l'utiliser plusieurs fois sur une page. Il se dégrade aussi gracieusement si JavaScript n'est pas disponible.
voici à quoi ressemblent deux de ces images sur une page. Dans cet exemple, le Mot de passe a été révélé en cliquant sur son œil.
$(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>
j'aime cette façon, pour modifier le type d'un élément d'entrée: old_input.clone.)(... Ici est 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 avec le nom" foo " doivent être remplacés par des cases à cocher. S'ils ne sont pas contrôlés, ils devraient 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();
});
}
)});
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;
j'ai créé une extension jQuery pour basculer entre le texte et le mot de passe. Fonctionne dans IE8 (probablement 6 et 7 aussi, mais pas testé) et ne perdra pas votre valeur ou 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 passer entre les deux ou donner une option pour "forcer" l'action basée sur quelque chose d'autre (comme une case à cocher): $('#element').togglePassword($checkbox.prop('checked'));
juste une autre option pour tous les amateurs de IE8, et il fonctionne parfait dans les nouveaux navigateurs. Vous pouvez simplement colorer le texte pour correspondre à l'arrière-plan de l'entrée. Si vous avez un seul champ, cela changera la couleur en noir lorsque vous cliquez sur/Mettre l'accent sur le champ. Je ne l'utiliserais pas sur un site public car cela "déconcerterait" la plupart des gens, mais je l'utilise dans une section ADMIN où une seule personne a accès aux mots de passe utilisateurs.
$('#MyPass').click(function() {
$(this).css('color', '#000000');
});
-OU-
$('#MyPass').focus(function() {
$(this).css('color', '#000000');
});
cela, également nécessaire, changera le texte de nouveau à blanc lorsque vous quittez le champ. Simple, simple, simple.
$("#MyPass").blur(function() {
$(this).css('color', '#ffffff');
});
[ Une Autre Option ] Maintenant, si vous avez plusieurs champs que vous avez verifié, tous avec le même ID, comme je l'utilise pour l', ajouter une classe de "pass" pour les champs que vous souhaitez masquer le texte. Définissez les champs de mot de passe tapez sur 'text'. De cette façon, seuls les champs avec une classe de 'pass' sera changé.
<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 modifie le texte blanc après vous laissez le champ.
$("[id^=inp_]").blur(function() {
if ($(this).hasClass("pass")) {
$(this).css('color', '#ffffff');
}
// rest of code
});