Esiste un modo per impedire che input type = "number" ottenga valori negativi?


Risposte:


658

Usa l' minattributo in questo modo:

<input type="number" min="0">


222
Questo bloccherà l'inserimento di un numero negativo usando i pulsanti freccia / spinner. Tuttavia, l'utente può comunque inserire manualmente un numero negativo e far leggere il valore di quel campo come numero negativo, bypassando così l'attributo min.
ecbrodie,

52
@demaniak No. E in che modo questa risposta ha ottenuto così tanti voti positivi quando risponde a metà la domanda è un mistero
GôTô

1
@Abraham Cosa succede se i dati caricati con il valore -ve nel modulo, non li contrassegnano come rossi.
Kamini,

2
Questo non funziona, l'utente può comunque inserire manualmente un numero negativo.
Altef quattro,

129

Non ero soddisfatto della risposta @Abhrabm perché:

Stava solo impedendo l' immissione di numeri negativi dalle frecce su / giù, mentre l'utente può digitare un numero negativo dalla tastiera.

La soluzione è prevenire con il codice chiave :

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

Chiarimento fornito da @Hugh Guiney :

Quali codici chiave vengono controllati:

  • 95, <106 corrisponde a Numpad da 0 a 9;
  • 47, <58 corrisponde da 0 a 9 nella riga dei numeri; e 8 è Backspace.

Quindi questo script impedisce l'immissione di una chiave non valida nell'input.


20
Eseguito l'upgrade ma penso che aiuterebbe a chiarire quali codici chiave vengono controllati:> 95, <106 corrisponde a Numpad da 0 a 9; > 47, <58 corrisponde da 0 a 9 nella riga dei numeri; e 8 è Backspace. Quindi questo script impedisce qualsiasi chiave tranne quelle di essere immesse. È approfondito ma penso che potrebbe essere eccessivo per i browser che supportano nativamente input di numeri, che già filtrano i tasti alfabetici (tranne caratteri come "e" che possono avere un significato numerico). Probabilmente basterebbe prevenire contro 189 (trattino) e 109 (sottrarre). E poi combinalo con min="0".
Hugh Guiney,

1
@Manwal Si limita a copiare e incollare i numeri usando la tastiera. E mi permette di copiare i numeri negativi incollati usando il mouse.
Beniton,

1
@Beniton Grazie per aver fornito questo caso d'uso. Puoi darmi una piccola idea di quello che stai facendo. Posso sempre aiutarti. Fornisci un piccolo codice o violino eseguibile. Puoi avere la convalida del livello di invio del modulo per nel tuo codice. Anche se ho sempre il check-in nel back-end se non autorizzo numeri negativi.
Manwal,

1
Fondamentalmente basta copiare e incollare nel campo. Non è davvero un caso speciale o altro. Invece di gestire la validazione tramite keycode, probabilmente è meglio farlo suChange o focusOut e costruire una piccola funzione di validazione per catturare eventuali numeri negativi.
ulisesrmzroche,

1
Dovrebbero essere inserite anche le condizioni per il tasto freccia (37, 38, 39, 41). || (e.keyCode>36 && e.keyCode<41)Ciò non consente all'utente di aumentare / ridurre il numero tramite la freccia su / giù e andare a destra / sinistra per modificare il numero.
vusan,

86

Per me la soluzione era:

<input type="number" min="0" oninput="this.value = Math.abs(this.value)">

1
La soluzione davvero migliore una volta che usi pattern e noformvalidate con angolare, poiché il modello non viene aggiornato se non all'interno dell'intervallo. Il mio caso:<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

funziona meglio quando l'utente sa che il valore predefinito è 0. L'altro utente saggio viene confuso sul backspace e premi perché il campo non si cancella. Tranne questo, è la soluzione migliore. + 1
Deep 3015

1
mi hai salvato la giornata
Stackmalux,

Questo funziona meglio e in caso di utilizzo anche dei decimali. Avevo usato un'altra risposta sopra, ha smesso di funzionare quando è consentito il decimale. C'è un modo per spostare questa risposta in modo che le persone possano usarla principalmente.
Subhan Ahmed il

31

Questo codice funziona bene per me. Potete per favore controllare:

<input type="number" name="test" min="0" oninput="validity.valid||(value='');">

2
Funziona ma svuotare l'intero input dopo aver provato a digitare -non è davvero una buona idea.
extempl

9
@extempl Sembra una giusta punizione per l'utente che cerca di inserire un negativo in un campo in cui il buon senso indica che non ci sono negativi.
KhoPhi,

3
<input type="number" name="test" min="0" oninput="validity.valid||(value=value.replace(/\D+/g, ''))">- questo rimuoverà tutti i simboli non cifre
Oleh Melnyk,

@Rexford Sono d'accordo, ma ho impostato min="0"quindi non ci sono nagativi. Se si desidera un valore negativo, rimuovere questo attributo.
Chinmay235,

1
Ho provato questo, ma ha anche impedito l'inserimento di numeri con punti decimali.
Klent,

21

Metodo semplice:

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


Bello e facile ... ma comunque, i numeri negativi possono essere incollati.
Ralf

10

Volevo consentire i numeri decimali e non cancellare l'intero input se veniva immesso un negativo. Questo funziona bene in Chrome almeno:

<input type="number" min="0" onkeypress="return event.charCode != 45">

Come aggiungere più numeri ASCII qui. per es. con 45 ho aggiunto anche 46. Come si può fare?
Pradeep Singh,

3
@PradeepSingh "return [45, 46] .indexOf (event.charCode) == -1"
ykay dice Reinstate Monica il

Per favore, pensa fuori dagli schemi. Sei davvero sicuro che a keypresssia l'unico modo per inserire un numero negativo in un input ...
Roko C. Buljan,

6

La risposta di @Manwal è buona, ma mi piace il codice con meno righe di codice per una migliore leggibilità. Mi piace anche usare l'utilizzo di onclick / onkeypress in html.

La mia soluzione suggerita fa lo stesso: Aggiungi

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

all'input html e

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

come una funzione javascript.

Come detto, fa lo stesso. È solo una preferenza personale su come risolvere il problema.


5

Solo per riferimento: con jQuery è possibile sovrascrivere valori negativi su focusout con il seguente codice:

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

Questo non sostituisce la convalida lato server!


Funziona bene SE l'utente si concentra fuori dal campo di input, tuttavia se preme immediatamente enter mentre è ancora nel campo; possono ancora inserire un numero negativo.
NemyaNation

3

Ecco una soluzione angolare 2:

crea una 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();
    }
  }
}

aggiungi OnlyNumber alle dichiarazioni in app.module.ts e usalo in questo modo ovunque nella tua app

<input OnlyNumber="true">

C'è un modo per consentire a Paste per questo? Inoltre ho cambiato il regex in: /^-?[0-9 lasting+(\.[0-9×*){0,1}$/g per consentire numeri negativi, ma non sembra funzionare?
Dave Nottage,

2
oninput="this.value=(this.value   < Number(this.min) || this.value   > Number(this.max))  ? '' : this.value;"

2
Sebbene questo frammento di codice possa risolvere la domanda, inclusa una spiegazione aiuta davvero a migliorare la qualità del tuo post. Ricorda che stai rispondendo alla domanda per i lettori in futuro e quelle persone potrebbero non conoscere i motivi del tuo suggerimento sul codice.
Sudheesh Singanamalla,

Sebbene questa possa essere la risposta corretta, manca di dettagli sufficienti. Spiega perché funziona. Quando usi Stack Overflow, considera che questa è una base di conoscenza vivente , le risposte che non condividono la conoscenza sono molto meno utili.
Marc LaFleur,

2

Basta aggiungere un altro modo per farlo (usando Angular) se non vuoi sporcare l'HTML con ancora più codice:

Devi solo iscriverti al campo valueChanges e impostare il valore come valore assoluto (facendo attenzione a non emettere un nuovo evento perché ciò causerà un altro valoreCambia quindi una chiamata ricorsiva e attiva un errore Dimensione massima chiamata superata)

CODICE HTML

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

CODICE TypeScript (all'interno del componente)

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'];
}

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


1

La risposta a questa non è utile. poiché funziona solo quando si usano i tasti su / giù, ma se si digita -11 non funzionerà. Quindi ecco una piccola correzione che uso

questo per numeri interi

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

questo quando hai numeri di prezzo

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

0

Questa soluzione consente tutte le funzionalità della tastiera incluso copia incolla con tastiera. Impedisce di incollare numeri negativi con il mouse. Funziona con tutti i browser e la demo su codepen utilizza bootstrap e jQuery. Questo dovrebbe funzionare con impostazioni e tastiere in lingua non inglese. Se il browser non supporta l'acquisizione degli eventi di incollaggio (IE), rimuoverà il segno negativo dopo l'attivazione. Questa soluzione si comporta come dovrebbe il browser nativo con min = 0 tipo = numero.

markup:

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

0

Ecco una soluzione che ha funzionato meglio di me per un campo QTY che consente solo numeri.

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

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.