Czy jest jakiś sposób, aby zapobiec wprowadzeniu wartości ujemnych typu wejściowego = „liczba”?


Odpowiedzi:


658

Użyj następującego minatrybutu :

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


222
Spowoduje to zablokowanie wprowadzania liczby ujemnej za pomocą przycisków strzałek / pokrętła. Jednak użytkownik nadal może ręcznie wprowadzić liczbę ujemną i odczytać wartość tego pola jako liczbę ujemną, omijając w ten sposób atrybut min.
ecbrodie

52
@demaniak Nie. W jaki sposób ta odpowiedź zyskała tak wiele pozytywnych opinii, gdy połowa odpowiedzi na pytanie, jest tajemnicą
GôTô,

1
@Abraham Co jeśli dane załadowane z wartością -ve w formularzu, nie oznaczą jej jako czerwonej.
Kamini

2
To nie działa, użytkownik może ręcznie wprowadzić liczbę ujemną.
Altef cztery

129

Nie jestem zadowolony z odpowiedzi @Abhrabm, ponieważ:

Zapobiegało to jedynie wprowadzaniu liczb ujemnych ze strzałek góra / dół, podczas gdy użytkownik może wpisać liczbę ujemną z klawiatury.

Rozwiązaniem jest zapobieganie za pomocą kodu klucza :

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

Wyjaśnienie dostarczone przez @Hugh Guiney :

Jakie kody kluczy są sprawdzane:

  • 95, <106 odpowiada Numpad od 0 do 9;
  • 47, <58 odpowiada 0 do 9 w wierszu liczb; a 8 to Backspace.

Ten skrypt zapobiega wprowadzaniu nieprawidłowego klucza do danych wejściowych.


20
Głosowałem, ale myślę, że pomogłoby wyjaśnić, które kody kluczy są sprawdzane:> 95, <106 odpowiada Numpad od 0 do 9; > 47, <58 odpowiada 0 do 9 w wierszu liczb; a 8 to Backspace. Zatem ten skrypt uniemożliwia wprowadzenie dowolnego klucza oprócz tych. Jest dokładny, ale myślę, że może to być przesada w przeglądarkach, które natywnie obsługują wprowadzanie liczb, które już odfiltrowują klawisze alfabetyczne (z wyjątkiem znaków takich jak „e”, które mogą mieć znaczenie numeryczne). Prawdopodobnie wystarczyłoby zapobiec 189 (kreska) i 109 (odjąć). A następnie połącz z min="0".
Hugh Guiney

1
@Manwal Ogranicza się do kopiowania i wklejania liczb za pomocą klawiatury. I pozwala mi skopiować wklejone liczby ujemne za pomocą myszy.
Beniton,

1
@Beniton Dzięki, podając ten przypadek użycia. Czy możesz mi powiedzieć niewiele o tym, co robisz? Zawsze mogę ci pomóc. Podaj niewielki kod lub skrzypkę. Możesz mieć formularz Prześlij weryfikację poziomu w swoim kodzie. Chociaż zawsze mam odprawę w Backend, jeśli nie zezwalam na liczby ujemne.
Manwal

1
Wystarczy skopiować i wkleić w polu. To naprawdę nie jest specjalny przypadek ani nic takiego. Zamiast obsługi sprawdzania poprawności za pomocą kodu dostępu, prawdopodobnie lepiej jest to zrobić na Change lub focusOut i zbudować małą funkcję sprawdzania poprawności, aby przechwycić dowolne liczby ujemne.
ulisesrmzroche

1
Należy również wprowadzić warunek klawisza strzałki (37, 38, 39, 41). || (e.keyCode>36 && e.keyCode<41)To nie pozwala użytkownikowi zwiększać / zmniejszać liczby za pomocą strzałki w górę / w dół i przechodzić w prawo / w lewo, aby edytować numer.
vusan

86

Dla mnie rozwiązaniem było:

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

1
Naprawdę najlepsze rozwiązanie, gdy użyjesz wzorca i noformvalidate z kątem, ponieważ model nie jest aktualizowany, jeśli nie mieści się w zakresie. Mój przypadek:<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

działa to najlepiej, gdy użytkownik wie, że wartością domyślną jest 0. Inny mądry użytkownik jest zdezorientowany na backspace, dlaczego pole nie jest czyszczone. Poza tym jest to najlepsze rozwiązanie. + 1
Głębokie 3015

1
uratowałeś mi dzień
stackmalux

Ten działa najlepiej, a także w przypadku dziesiętnego. Użyłem innej odpowiedzi powyżej, przestała działać, gdy dozwolona jest liczba dziesiętna. Czy istnieje sposób, aby przenieść tę odpowiedź na wyższy, aby ludzie mogli z niej korzystać w większości.
Subhan Ahmed

31

Ten kod działa dla mnie dobrze. Czy możesz proszę sprawdzić:

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

2
Działa to, ale opróżnianie całego wejścia po próbie wpisania -nie jest dobrym pomysłem.
extempl

9
@extempl Brzmi jak sprawiedliwa kara dla użytkownika próbującego wprowadzić negatyw w polu, w którym zdrowy rozsądek wskazuje, że nie ma żadnych negatywów.
KhoPhi,

3
<input type="number" name="test" min="0" oninput="validity.valid||(value=value.replace(/\D+/g, ''))">- spowoduje to usunięcie wszystkich symboli innych niż cyfry
Oleh Melnyk

@Rexford Zgadzam się, ale ustawiłem, min="0"więc nie ma żadnych nagród. Jeśli chcesz uzyskać wartość ujemną, usuń ten atrybut.
Chinmay235 16.04.18

1
Próbowałem tego, ale zapobiegało to wprowadzaniu liczb z kropkami dziesiętnymi.
klent

21

Łatwa metoda:

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


Ładne i łatwe ... ale nadal można wkleić liczby ujemne.
Ralf

10

Chciałem zezwolić na liczby dziesiętne i nie wyczyścić całego wejścia, jeśli wprowadzono ujemny. Działa to dobrze w chrome przynajmniej:

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

Jak dodać tutaj więcej numeru ascii. na przykład z 45 i wana dodaj także 46. Jak można to zrobić?
Pradeep Singh,

3
@PradeepSingh "return [45, 46] .indexOf (event.charCode) == -1"
porządku, mówi Przywróć Monikę

Proszę pomyśleć po wyjęciu z pudełka. Czy naprawdę jesteś pewien, że keypressto jedyny sposób, aby wprowadzić liczbę ujemną w danych wejściowych ...
Roko C. Buljan,

6

Odpowiedź @Manwal jest dobra, ale lubię kod z mniejszą liczbą wierszy kodu dla lepszej czytelności. Lubię też używać użycia onclick / onkeypress w HTML.

Moje sugerowane rozwiązanie robi to samo: Dodaj

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

do wejścia HTML i

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

jako funkcja javascript.

Jak powiedziano, robi to samo. To tylko osobiste preferencje dotyczące rozwiązania problemu.


5

Tylko w celach informacyjnych: za pomocą jQuery można zastąpić wartości ujemne podczas focusout następującym kodem:

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

Nie zastępuje to sprawdzania poprawności po stronie serwera!


Działa to dobrze, JEŚLI użytkownik skupia się poza polem wejściowym, jednak jeśli natychmiast naciśnie klawisz Enter, będąc jeszcze w polu; nadal mogą wprowadzić liczbę ujemną.
NemyaNation,

3

Oto rozwiązanie kątowe 2:

utwórz klasę 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();
    }
  }
}

dodaj OnlyNumber do deklaracji w app.module.ts i używaj w ten sposób w dowolnym miejscu w swojej aplikacji

<input OnlyNumber="true">

Czy istnieje sposób na zezwolenie na to w przypadku Paste? Zmieniłem także wyrażenie regularne na: /^-?[0-9]+(\.[0-9]*){0,1}$/g, aby zezwolić na liczby ujemne, ale wydaje się, że to nie działa?
Dave Nottage

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

2
Ten fragment kodu może rozwiązać pytanie, ale wyjaśnienie naprawdę pomaga poprawić jakość posta. Pamiętaj, że w przyszłości odpowiadasz na pytanie dla czytelników, a ci ludzie mogą nie znać przyczyn Twojej sugestii kodu.
Sudheesh Singanamalla

Chociaż może to być poprawna odpowiedź, brakuje w niej wystarczająco dużo szczegółów. Wyjaśnij, dlaczego to działa. Korzystając z przepełnienia stosu, pamiętaj, że jest to żywa baza wiedzy , odpowiedzi, które nie dzielą się wiedzą, są znacznie mniej przydatne.
Marc LaFleur

2

Wystarczy dodać inny sposób na zrobienie tego (używając Angulara), jeśli nie chcesz wyczyścić kodu HTML jeszcze większą ilością kodu:

Musisz tylko zasubskrybować wartość pola Change i ustawić wartość jako wartość bezwzględną (uważając, aby nie emitować nowego zdarzenia, ponieważ spowoduje to kolejną wartość. Zmień zatem połączenie rekurencyjne i wywołaj błąd przekroczenia maksymalnego rozmiaru połączenia)

KOD HTML

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

TypeScript CODE (Inside your Component)

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

Odpowiedź na to pytanie nie jest pomocna. ponieważ działa tylko wtedy, gdy używasz klawiszy góra / dół, ale jeśli wpiszesz -11, to nie zadziała. Oto mała poprawka, której używam

ten dla liczb całkowitych

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

ten, gdy masz liczby cen

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

To rozwiązanie umożliwia korzystanie z wszystkich funkcji klawiatury, w tym kopiowanie wklejaniem za pomocą klawiatury. Zapobiega wklejaniu liczb ujemnych za pomocą myszy. Działa ze wszystkimi przeglądarkami i wersją demo na codepen używa bootstrap i jQuery. Powinno to działać z ustawieniami i klawiaturami innymi niż angielski. Jeśli przeglądarka nie obsługuje przechwytywania zdarzenia wklejania (IE), usunie znak ujemny po wyostrzeniu. To rozwiązanie zachowuje się tak jak natywna przeglądarka z min = 0 type = number.

Narzut:

<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

Oto rozwiązanie, które najlepiej działało dla mnie w polu QTY, która dopuszcza tylko liczby.

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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.