web-dev-qa-db-fra.com

Remplacer un point en utilisant JavaScript supprime tout

Je suis entré dans un problème étrange. Lorsque vous essayez de remplacer un point sur une entrée numérique, au lieu de ne remplacer que ce point, il efface la totalité de l'entrée.

$("[data-input-payment-id]").on("keyup", function(e) {
  var test_value = $(this).val().replace(/\./g, "");
  $(this).val(test_value);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="number" data-input-payment-id="12">

JSFIDDLE

Comment puis-je le changer pour qu'il ne supprime que les points?

16
Ellisan

Je pense (deviner) que c'est parce que vous utilisez type="number". Ensuite, les chiffres suivis d'un point, par ex. 123. n'est pas un nombre valide et val renvoie un blanc.

Vous pouvez essayer ceci à la place:

$("[data-input-payment-id]").on("keyup", function(e) {
  var test_value = this.value.replace(/[^\d,]/g, "");
  $(this).val(test_value);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input data-input-payment-id="12">

Ceci utilise un type de texte normal et filtre tout sauf les chiffres dans le remplacement.

Modifier:
Changé l'expression régulière pour qu'elle corresponde à autre chose que les chiffres et les virgules .

11
SamWhan

Je voudrais:

  • Au lieu de l'événement keyup, écoutez l'événement input. De cette façon, vous pouvez également autoriser le collage.
  • Conservez la valeur correcte précédente pour pouvoir y revenir. Cela est nécessaire car les entrées type=number auront une chaîne vide comme valeur dès que l'entrée sera invalide (sous forme de nombre). Je voudrais stocker cette valeur correcte précédente dans une propriété data de l'élément input
  • Avec l'utilisation de la propriété validity.stepMismatch, vous pouvez savoir si la valeur actuelle viole la propriété step de la input qui est par défaut à 1. Avec un pas de 1, cela signifie que la saisie d'un nombre avec un séparateur décimal sera considérée comme une non-concordance.
  • Comme un séparateur décimal final ne donnera pas (encore) un nombre fractionnaire, il passera la validation ci-dessus. Donc, renvoyez la valeur dans l'entrée lorsque tout va bien: cela éliminera tout séparateur décimal de fin qui aurait pu être saisi.

$("[data-input-payment-id]").on("input", function (e) {
    if (!this.validity.stepMismatch) {
        $(this).data("lastValid", $(this).val());
    };
    $(this).val($(this).data("lastValid") || "");  
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="number"data-input-payment-id="12">

Cela dit, je ne suis personnellement pas en faveur du blocage de la saisie de l’utilisateur: ils pourraient penser un instant que leur clavier est en panne. Il est à mon avis préférable de permettre à l'utilisateur de taper n'importe quoi et d'indiquer simplement avec un message à côté de l'entrée que l'entrée n'est pas valide (jusqu'à ce qu'elle le soit).

2
trincot

Ce n'est pas vraiment une solution comme j'aimerais personnellement la voir, mais voici ce que j'ai fait pour résoudre le problème. J'ai changé le code JavaScript pour écouter le code clé 46 (le .) et je renvoie false sur l'écouteur d'événement de collage pour désactiver le collage d'une valeur dans l'entrée.

$("[data-input-payment-id]").on("keypress", function(e) {
  var key = e.charCode ? e.charCode : e.keyCode;
  if (key == 46) {
    return false;
  }
});
$("[data-input-payment-id]").on("paste", function(e) {
  return false;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="number" data-input-payment-id="12">

Cela fonctionne au moins dans Chrome et Edge.

2
Ellisan

Votre exemple Keypress m'a donné cette idée. Si vous pouvez intercepter l'événement de frappe, il est possible de vérifier toute validation avant d'ajouter la valeur réelle. Cet exemple n'exige également aucune condition et permet de filtrer toute valeur non numérique.

$("[data-input-payment-id]").on("keypress", function(e) {
  if ((this.value + e.key).match(/\D/)) {
    return false;
  }
});
$("[data-input-payment-id]").on("paste", function(e) {
  var pasteData = (e.originalEvent.clipboardData || window.clipboardData).getData('text');
  pasteData = pasteData.replace(/\D/g, '');
  this.value = this.value + pasteData;
  return false;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="number" data-input-payment-id="12">

  • Permet de coller des données avec filtrage
  • Aucun conditionnel spécifique
  • Peut être modifié pour une validation personnalisée

http://jsfiddle.net/xpvt214o/511118/

2
cnvzmxcvmcx

Voir Documents MDN on inputs de type number:

Valeur

Un nombre représentant un nombre, ou vide

Si la chaîne d'entrée ne peut pas être convertie en un nombre correct, par exemple si la chaîne contient deux points, l'accès à la propriété .value renvoie la chaîne vide.

Les fonctions .value (et val()) renverront toujours strings, mais ces chaînes doivent représenter des nombres valides (ou être la chaîne vide). Plutôt que de définir inconditionnellement la valeur de l'élément, vérifiez simplement si la valeur n'est pas la chaîne vide en premier:

$("[data-input-payment-id]").on("keyup", function(e) {
  const val = $(this).val();
  if (val === '') return;
  var test_value = $(this).val().replace(/\./g, "");
  $(this).val(test_value);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="number" data-input-payment-id="12">

Ou vous pouvez utiliser une entrée de texte et éventuellement une pattern:

$("[data-input-payment-id]").on("keyup", function(e) {
  const val = $(this).val();
  var test_value = $(this).val().replace(/\./g, "");
  $(this).val(test_value);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
  <input data-input-payment-id="12">
  <input type="submit">
</form>

<form>
<input pattern="^\d+$" data-input-payment-id="12">
<input type="submit">
</form>

1
CertainPerformance

$(this).val() renvoie une chaîne vide si une entrée avec type="number" a plus d'un . 

Vous pouvez résoudre ce problème en exécutant uniquement le remplacement de la valeur si $(this).val() ne renvoie pas de chaîne vide.

0
Lars Munkholm