web-dev-qa-db-fra.com

Entrée HTML qui ne prend que des chiffres et le symbole +

J'essaie de créer une entrée de texte personnalisée pour les numéros de téléphone qui accepte uniquement les chiffres et le symbole plus (+); tous les autres personnages doivent être jetés et ne doivent pas apparaître sur le terrain.

J'essaie de le faire en utilisant un gestionnaire d'événements (onkeydown/onkeypress) et en rejetant les entrées correspondant à d'autres clés. Cependant, je ne peux pas trouver de moyen multi-navigateur pour le faire. Voici les approches que j'ai essayées et qui ne fonctionnent pas:

  • Utiliser l'événement onkeypress et regarder event.key pour déterminer quelle touche a été pressée: ne fonctionne pas sur Chrome = (voir http://caniuse.com/keyboardevent-key ). Existe-t-il une solution de contournement pour plusieurs navigateurs?

  • L'utilisation de l'événement onkeycode et la recherche dans event.keyCode: ne fonctionne pas lorsque nous devons appuyer sur plusieurs touches pour imprimer un caractère (par exemple, un clavier anglais mise en page nécessite d'appuyer sur Maj et = pour donner +). De plus, il permet à des caractères tels que! @ # $% ˆ & * () d'apparaître, car ils apparaissent lorsque vous appuyez sur Maj et sur un nombre. (C'est l'approche suivie dans le code clé JavaScript autorise uniquement le nombre et le symbole plus , mais cela ne m'aide pas beaucoup;))

  • L'utilisation de l'attribut de modèle HTML: cela ne semble pas vraiment empêcher les gens d'écrire ce qu'ils ressentent.

Merci!

14
unpollito

Il existe une autre solution, vous pouvez utiliser Array.prototype.filter() pour supprimer les mauvais caractères, et Array.prototype.join() pour recréer la chaîne avant de l'insérer dans l'entrée.

Vous pouvez utiliser oninput événement. Il exécute un JavaScript lorsqu'un utilisateur écrit quelque chose dans un <input> champ.


Voir l'exemple ci-dessous

var inputEl = document.getElementById('tel');
var goodKey = '0123456789+ ';

var checkInputTel = function(e) {
  var key = (typeof e.which == "number") ? e.which : e.keyCode;
  var start = this.selectionStart,
    end = this.selectionEnd;

  var filtered = this.value.split('').filter(filterInput);
  this.value = filtered.join("");

  /* Prevents moving the pointer for a bad character */
  var move = (filterInput(String.fromCharCode(key)) || (key == 0 || key == 8)) ? 0 : 1;
  this.setSelectionRange(start - move, end - move);
}

var filterInput = function(val) {
  return (goodKey.indexOf(val) > -1);
}

inputEl.addEventListener('input', checkInputTel);
<input type='tel' id='tel' />

Remarque: J'utilise le type d'entrée tel pour afficher le pavé numérique par défaut dans un smartphone ou une tablette.

tel: html5 Un contrôle pour entrer un numéro de téléphone; les sauts de ligne sont automatiquement supprimés de la valeur d'entrée, mais aucune autre syntaxe n'est appliquée. Vous pouvez utiliser des attributs tels que pattern et maxlength pour restreindre les valeurs entrées dans le contrôle. Les pseudo-classes : valid et : invalid CSS sont appliquées selon les besoins.

Référence: MDN <input>

14
R3tep

Essayez toujours de faire une validation côté serveur, cela est destiné à "aider" l'utilisateur, pas à valider les données, (vous pouvez toujours ouvrir votre console et modifier la valeur de la valeur d'entrée comme vous le souhaitez)

Maintenant, la méthode que j'utiliserais est:

Vérifiez la valeur de l'entrée entière lors du changement et faites-la passer par une expression régulière pour nettoyer les caractères indésirables, tout en gardant une trace de l'endroit où se trouvait le "curseur de texte"

const tel = document.getElementById('tel');

tel.addEventListener('input', function() {
  let start = this.selectionStart;
  let end = this.selectionEnd;
  
  const current = this.value
  const corrected = current.replace(/([^+0-9]+)/gi, '');
  this.value = corrected;
  
  if (corrected.length < current.length) --end;
  this.setSelectionRange(start, end);
});
<input type="tel" id="tel">

Vous pourriez faire un regex beaucoup plus "précis" selon ce que vous voulez, voici un bel outil pour ça: RegExr

9
Aramil Rey

Je vous suggère de regarder ce projet. https://github.com/igorescobar/jQuery-Mask-Plugin/

Vous pouvez l'utiliser tel quel: $('.phone').mask('0000-0000'); Exemple: https://igorescobar.github.io/jQuery-Mask-Plugin/

Ou vous pouvez lire le code source et voir comment ils le résolvent.

8
yeouuu

Cette approche générique robuste est inspirée de la réponse de @ R3tep. Il permet de définir des motifs d'expression rationnelle via le data-filter attribut similaire à attribut de modèle :

// Apply filter to all inputs with data-filter:
let inputs = document.querySelectorAll('input[data-filter]');

for (let input of inputs) {
  let state = {
    value: input.value,
    start: input.selectionStart,
    end: input.selectionEnd,
    pattern: RegExp('^' + input.dataset.filter + '$')
  };
  
  input.addEventListener('input', event => {
    if (state.pattern.test(input.value)) {
      state.value = input.value;
    } else {
      input.value = state.value;
      input.setSelectionRange(state.start, state.end);
    }
  });

  input.addEventListener('keydown', event => {
    state.start = input.selectionStart;
    state.end = input.selectionEnd;
  });
}
<input type='tel' data-filter='[0-9|+]*' placeholder='123+456'>
<input type='tel' data-filter='(\+|(\+[1-9])?[0-9]*)' placeholder='+10123'>
<input type='text' data-filter='([A-Z]?|[A-Z][a-z]*)' placeholder='Abcdefg'>
<input type='text' data-filter='([A-Z]{0,3}|[A-Z]{3}[0-9]*)' placeholder='ABC123'>
7
le_m

utiliser une entrée

type = "tel" ou "téléphone"

Il montre le pavé numérique par défaut dans les mobiles.

J'espère que cela vous aidera :)

5
bhagya

En utilisant une combinaison d'un écouteur d'événement keyup, de quelques méthodes de comparaison RegEx/String et d'une variable intermédiaire, j'ai pu trouver ce qui suit:

var ele = document.getElementById('phone');
var curr = "";
var regexPatt = /^(0|[1-9][0-9]*)$/;
ele.addEventListener('keyup',function(e){
  var code = e.keyCode || e.which;
  if(this.value.match(regexPatt) || this.value.indexOf('+') > -1 || code == 8){
    curr = this.value;
    this.value = curr;
  } else {
    this.value = curr;
  }
});

Jetez un œil au violon: https://jsfiddle.net/Lg31pomp/2/

Cela semble fonctionner avec des chiffres, le + ainsi que si l'utilisateur retourne en arrière l'élément d'entrée.

2
A.Sharma