Existe-t-il un moyen d'empêcher le type d'entrée = «nombre» d'obtenir des valeurs négatives?

302

Je veux obtenir uniquement des valeurs positives, existe-t-il un moyen de l'empêcher d'utiliser uniquement du HTML
Veuillez ne pas suggérer de méthode de validation

Capture d'écran du contrôle d'entrée

Tural Ali
la source
3
Ce fil répond à la même question dans une bien meilleure mesure: stackoverflow.com/questions/31575496/…
PiotrWolkowski

Réponses:

658

Utilisez l' minattribut comme ceci:

<input type="number" min="0">
Abraham
la source
6
Voici une source de référence plus fiable .
Álvaro González
222
Cela empêchera la saisie d'un nombre négatif à l'aide des boutons fléchés / de la flèche. Cependant, l'utilisateur peut toujours entrer manuellement un nombre négatif et faire lire la valeur de ce champ comme un nombre négatif, contournant ainsi l'attribut min.
ecbrodie
52
@demaniak No. Et comment cette réponse a-t-elle obtenu autant de votes positifs lorsqu'elle répond à moitié à la question est un mystère
GôTô
1
@Abraham Que faire si les données chargées avec la valeur -ve dans le formulaire, elles ne le marquent pas comme rouge.
Kamini
2
Cela ne fonctionne pas, l'utilisateur peut toujours saisir manuellement un nombre négatif.
Altef quatre
129

Je n'étais pas satisfait de la réponse @Abhrabm car:

Cela empêchait uniquement la saisie de nombres négatifs à partir des flèches haut / bas, tandis que l'utilisateur pouvait taper un nombre négatif à partir du clavier.

La solution consiste à éviter avec le code clé :

// Select your input element.
var number = document.getElementById('number');

// Listen for input event on numInput.
number.onkeydown = function(e) {
    if(!((e.keyCode > 95 && e.keyCode < 106)
      || (e.keyCode > 47 && e.keyCode < 58) 
      || e.keyCode == 8)) {
        return false;
    }
}
<form action="" method="post">
  <input type="number" id="number" min="0" />
  <input type="submit" value="Click me!"/>
</form>

Précision fournie par @Hugh Guiney :

Quels codes clés sont vérifiés:

  • 95, <106 correspond au pavé numérique 0 à 9;
  • 47, <58 correspond à 0 à 9 sur la ligne numérique; et 8 est Backspace.

Ce script empêche donc la saisie d'une clé non valide en entrée.

Manwal
la source
20
Surévalué mais je pense que cela aiderait à clarifier quels codes clés sont vérifiés:> 95, <106 correspond au pavé numérique 0 à 9; > 47, <58 correspond à 0 à 9 sur la ligne numérique; et 8 est Backspace. Donc, ce script empêche toute clé sauf celles qui sont entrées. C'est approfondi mais je pense que cela pourrait être exagéré pour les navigateurs qui prennent en charge nativement les entrées numériques, qui filtrent déjà les clés alphabétiques (à l'exception des caractères comme "e" qui peuvent avoir une signification numérique). Il suffirait probablement de prévenir contre 189 (tiret) et 109 (soustraire). Et puis combinez avec min="0".
Hugh Guiney
1
@Manwal Il se limite à copier et coller des nombres à l'aide du clavier. Et me permet de copier-coller des nombres négatifs à l'aide de la souris.
Beniton
1
@Beniton Merci d'avoir donné ce cas d'utilisation. Pouvez-vous me donner une petite idée de ce que vous faites, je peux toujours vous aider. Veuillez fournir un petit code exécutable ou un violon. Vous pouvez avoir le formulaire Valider le niveau de validation pour dans votre code. Bien que j'aie toujours un chèque dans le backend si je n'autorise pas les nombres négatifs.
Manwal
1
Il suffit de copier-coller dans le champ. Ce n'est pas vraiment un cas spécial ou quoi que ce soit. Au lieu de gérer la validation via le code clé, il est probablement préférable de le faire sur Change ou focusOut et de créer une petite fonction de validation pour attraper les nombres négatifs.
ulisesrmzroche
1
La condition de la touche fléchée (37, 38, 39, 41) doit également être indiquée. || (e.keyCode>36 && e.keyCode<41)Cela ne permet pas à l'utilisateur d'augmenter / diminuer le nombre via la flèche haut / bas et d'aller à droite / gauche pour modifier le nombre.
vusan
86

Pour moi, la solution était:

<input type="number" min="0" oninput="this.value = Math.abs(this.value)">
Renato Machado
la source
1
Vraiment la meilleure solution une fois que vous utilisez pattern et noformvalidate avec angular, car le modèle n'est pas mis à jour s'il n'est pas dans la plage. Mon cas:<input ng-model="row.myValue" type="{{row.code == 1 ? 'text' : 'number'}}" min="0" ng-pattern="..." noformvalidate oninput="if (this.type=='text') this.value=Math.abs(this.value) ">
sebius
cela fonctionne mieux lorsque l'utilisateur sait que la valeur par défaut est 0. Un autre utilisateur sage est confus lors du retour arrière, appuyez sur la raison pour laquelle le champ n'est pas effacé. Sauf cela, c'est la meilleure solution. + 1
Deep 3015
1
tu as sauvé ma journée
stackmalux
Celui-ci fonctionne mieux, et en cas d'utilisation décimale également. J'avais utilisé une autre réponse ci-dessus, elle a cessé de fonctionner lorsque la décimale doit être autorisée. Est-il possible de déplacer cette réponse vers le haut afin que les gens puissent l'utiliser principalement.
Subhan Ahmed
31

Ce code fonctionne bien pour moi. Peux tu vérifier s'il te plaît:

<input type="number" name="test" min="0" oninput="validity.valid||(value='');">
Chinmay235
la source
2
Cela fonctionne, mais vider l'intégralité de l'entrée après avoir essayé de taper -n'est pas vraiment une bonne idée.
extempl
9
@extempl Cela ressemble à une punition juste pour l'utilisateur qui essaie d'entrer un négatif dans un champ où le bon sens indique qu'il n'y a pas de négatif.
KhoPhi
3
<input type="number" name="test" min="0" oninput="validity.valid||(value=value.replace(/\D+/g, ''))">- cela supprimera tous les symboles non numériques
Oleh Melnyk
@Rexford Je suis d'accord, mais j'ai mis en place min="0"donc il n'y a pas de nagatifs. Si vous souhaitez une valeur négative, supprimez cet attribut.
Chinmay235
1
J'ai essayé mais cela a également empêché la saisie de nombres avec des décimales.
klent
21

Méthode simple:

<input min='0' type="number" onkeypress="return (event.charCode == 8 || event.charCode == 0) ? null : event.charCode >= 48 && event.charCode <= 57">

Rouvé
la source
Agréable et facile ... mais quand même, des nombres négatifs peuvent être collés.
Ralf
10

Je voulais autoriser les nombres décimaux et ne pas effacer la totalité de l'entrée si un négatif était entré. Cela fonctionne bien en chrome au moins:

<input type="number" min="0" onkeypress="return event.charCode != 45">
ykay dit Réintégrer Monica
la source
Comment peut ajouter plus de nombre ascii ici. par exemple. avec 45 i wana ajouter 46 aussi. Comment cela peut-il être fait?
Pradeep Singh
3
@PradeepSingh "return [45, 46] .indexOf (event.charCode) == -1"
ykay dit de rétablir Monica
Veuillez penser hors de la boîte. Êtes-vous vraiment sûr que keypressc'est la seule façon d'entrer un nombre négatif dans une entrée ...
Roko C. Buljan
6

La réponse @Manwal est bonne, mais j'aime le code avec moins de lignes de code pour une meilleure lisibilité. J'aime aussi utiliser à la place l'utilisation onclick / onkeypress en html.

Ma solution suggérée fait de même: Ajouter

min="0" onkeypress="return isNumberKey(event)"

à l'entrée html et

function isNumberKey(evt){
    var charCode = (evt.which) ? evt.which : event.keyCode;
    return !(charCode > 31 && (charCode < 48 || charCode > 57));
}

comme une fonction javascript.

Comme je l'ai dit, il fait de même. C'est juste une préférence personnelle sur la façon de résoudre le problème.

Chris H.
la source
5

Juste pour référence: avec jQuery vous pouvez écraser les valeurs négatives sur focusout avec le code suivant:

$(document).ready(function(){
    $("body").delegate('#myInputNumber', 'focusout', function(){
        if($(this).val() < 0){
            $(this).val('0');
        }
    });
});

Cela ne remplace pas la validation côté serveur!

Hafenkranich
la source
Cela fonctionne très bien SI l'utilisateur se concentre hors du champ de saisie, cependant s'il appuie immédiatement sur Entrée alors qu'il est encore dans le champ; ils peuvent toujours entrer un nombre négatif.
NemyaNation du
3

Voici une solution angulaire 2:

créer une classe OnlyNumber

import {Directive, ElementRef, HostListener} from '@angular/core';

@Directive({
  selector: '[OnlyNumber]'
})
export class OnlyNumber {

  // Allow decimal numbers. The \. is only allowed once to occur
  private regex: RegExp = new RegExp(/^[0-9]+(\.[0-9]*){0,1}$/g);

  // Allow key codes for special events. Reflect :
  // Backspace, tab, end, home
  private specialKeys: Array<string> = ['Backspace', 'Tab', 'End', 'Home'];

  constructor(private el: ElementRef) {
  }

  @HostListener('keydown', ['$event'])
  onKeyDown(event: KeyboardEvent) {
    // Allow Backspace, tab, end, and home keys
    if (this.specialKeys.indexOf(event.key) !== -1) {
      return;
    }

    // Do not use event.keycode this is deprecated.
    // See: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode
    let current: string = this.el.nativeElement.value;
    // We need this because the current value on the DOM element
    // is not yet updated with the value from this event
    let next: string = current.concat(event.key);
    if (next && !String(next).match(this.regex)) {
      event.preventDefault();
    }
  }
}

ajoutez OnlyNumber aux déclarations dans app.module.ts et utilisez comme ça n'importe où dans votre application

<input OnlyNumber="true">
Sarath Nagesh
la source
Existe-t-il un moyen d'autoriser le collage pour cela? J'ai également changé l'expression régulière en: /^-?[0-9[+(\.[0-9[*){0,1}$/g pour autoriser les nombres négatifs, mais cela ne semble pas fonctionner?
Dave Nottage
2
oninput="this.value=(this.value   < Number(this.min) || this.value   > Number(this.max))  ? '' : this.value;"
user9276950
la source
2
Bien que cet extrait de code puisse résoudre la question, y compris une explication aide vraiment à améliorer la qualité de votre message. N'oubliez pas que vous répondrez à la question des lecteurs à l'avenir et que ces personnes ne connaissent peut-être pas les raisons de votre suggestion de code.
Sudheesh Singanamalla
Bien que cela puisse être la bonne réponse, il manque suffisamment de détails. Veuillez expliquer pourquoi cela fonctionne. Lorsque vous utilisez Stack Overflow, considérez qu'il s'agit d'une base de connaissances vivante , les réponses qui ne partagent pas les connaissances sont beaucoup moins utiles.
Marc LaFleur
2

Ajouter simplement une autre façon de faire cela (en utilisant Angular) si vous ne voulez pas salir le HTML avec encore plus de code:

Il vous suffit de vous abonner au champ valueChanges et de définir la valeur comme une valeur absolue (en prenant soin de ne pas émettre un nouvel événement car cela provoquera un autre valueChange donc un appel récursif et déclenchera une erreur Taille d'appel maximale dépassée)

CODE HTML

<form [formGroup]="myForm">
    <input type="number" formControlName="myInput"/>
</form>

CODE TypeScript (à l'intérieur de votre composant)

formGroup: FormGroup;

ngOnInit() { 
    this.myInput.valueChanges 
    .subscribe(() => {
        this.myInput.setValue(Math.abs(this.myInput.value), {emitEvent: false});
    });
}

get myInput(): AbstractControl {
    return this.myForm.controls['myInput'];
}
Pedro B.
la source
1

<input type="number" name="credit_days" pattern="[^\-]+" 
    #credit_days="ngModel" class="form-control" 
    placeholder="{{ 'Enter credit days' | translate }}" min="0" 
    [(ngModel)]="provider.credit_days"
    onkeypress="return (event.charCode == 8 || event.charCode == 0 || 
    event.charCode == 13) ? null : event.charCode >= 48 && event.charCode <= 
    57" onpaste="return false">

Hui Lin
la source
1

La réponse à cela n'est pas utile. car cela ne fonctionne que lorsque vous utilisez les touches haut / bas, mais si vous tapez -11, cela ne fonctionnera pas. Voici donc un petit correctif que j'utilise

celui-ci pour les entiers

  $(".integer").live("keypress keyup", function (event) {
    //    console.log('int = '+$(this).val());
    $(this).val($(this).val().replace(/[^\d].+/, ""));
    if (event.which != 8 && (event.which < 48 || event.which > 57))
    {
        event.preventDefault();
    }
   });

celui-ci quand vous avez des numéros de prix

        $(".numeric, .price").live("keypress keyup", function (event) {
     //    console.log('numeric = '+$(this).val());
    $(this).val($(this).val().replace(/[^0-9\,\.]/g, ''));

    if (event.which != 8 && (event.which != 44 || $(this).val().indexOf(',') != -1) && (event.which < 48 || event.which > 57)) {
        event.preventDefault();
    }
   });
Ahmed Sunny
la source
0

Cette solution permet toutes les fonctionnalités du clavier, y compris copier-coller avec le clavier. Il empêche le collage de nombres négatifs avec la souris. Il fonctionne avec tous les navigateurs et la démo sur codepen utilise bootstrap et jQuery. Cela devrait fonctionner avec des paramètres et des claviers non anglais. Si le navigateur ne prend pas en charge la capture d'événement de collage (IE), il supprimera le signe négatif après la mise au point. Cette solution se comporte comme le navigateur natif devrait le faire avec min = 0 type = nombre.

Balisage:

<form>
  <input class="form-control positive-numeric-only" id="id-blah1" min="0" name="nm1" type="number" value="0" />
  <input class="form-control positive-numeric-only" id="id-blah2" min="0" name="nm2" type="number" value="0" />
</form>

Javascript

$(document).ready(function() {
  $("input.positive-numeric-only").on("keydown", function(e) {
    var char = e.originalEvent.key.replace(/[^0-9^.^,]/, "");
    if (char.length == 0 && !(e.originalEvent.ctrlKey || e.originalEvent.metaKey)) {
      e.preventDefault();
    }
  });

  $("input.positive-numeric-only").bind("paste", function(e) {
    var numbers = e.originalEvent.clipboardData
      .getData("text")
      .replace(/[^0-9^.^,]/g, "");
    e.preventDefault();
    var the_val = parseFloat(numbers);
    if (the_val > 0) {
      $(this).val(the_val.toFixed(2));
    }
  });

  $("input.positive-numeric-only").focusout(function(e) {
    if (!isNaN(this.value) && this.value.length != 0) {
      this.value = Math.abs(parseFloat(this.value)).toFixed(2);
    } else {
      this.value = 0;
    }
  });
});
wilsotc
la source
0

Voici une solution qui a fonctionné le mieux pour moi pour un champ QTY qui n'autorise que les chiffres.

// Only allow numbers, backspace and left/right direction on QTY input
    if(!((e.keyCode > 95 && e.keyCode < 106) // numpad numbers
        || (e.keyCode > 47 && e.keyCode < 58) // numbers
        || [8, 9, 35, 36, 37, 39].indexOf(e.keyCode) >= 0 // backspace, tab, home, end, left arrow, right arrow
        || (e.keyCode == 65 && (e.ctrlKey === true || e.metaKey === true)) // Ctrl/Cmd + A
        || (e.keyCode == 67 && (e.ctrlKey === true || e.metaKey === true)) // Ctrl/Cmd + C
        || (e.keyCode == 88 && (e.ctrlKey === true || e.metaKey === true)) // Ctrl/Cmd + X
        || (e.keyCode == 86 && (e.ctrlKey === true || e.metaKey === true)) // Ctrl/Cmd + V
    )) {
        return false;
    }
TheRealJAG
la source
0

If Number is Negative or Positive Using ES6s Math.Sign

const num = -8;
// Old Way
num === 0 ? num : (num > 0 ? 1 : -1); // -1

// ES6 Way
Math.sign(num); // -1

Israt Jahan Simu
la source