Есть ли способ предотвратить ввод отрицательных значений типа type = «number»?


302

Я хочу получить только положительные значения, есть ли способ предотвратить это, используя только HTML
Пожалуйста, не предлагайте метод проверки

Снимок экрана управления вводом


3
Эта тема отвечает на тот же вопрос в гораздо лучшей степени: stackoverflow.com/questions/31575496/…
PiotrWolkowski

Ответы:


658

Используйте minатрибут как это:

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


222
Это заблокирует ввод отрицательного числа с помощью кнопок со стрелками / счетчика. Однако пользователь все еще может вручную ввести отрицательное число и считать значение этого поля как отрицательное число, минуя атрибут min.
Экброди

52
@demaniak Нет. И как этот ответ получил столько голосов, когда наполовину ответил на вопрос - загадка
GôTô

1
@Abraham Что делать, если данные, загруженные со значением -ve в форме, не помечают его как красный.
Камини

2
Это не работает, пользователь все еще может ввести отрицательное число вручную.
Альтеф четыре

129

Я не был удовлетворен ответом @Abhrabm, потому что:

Он только предотвращал ввод отрицательных чисел из стрелок вверх / вниз, тогда как пользователь мог вводить отрицательные числа с клавиатуры.

Решение состоит в том, чтобы предотвратить с помощью ключевого кода :

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

Уточнение предоставлено @Hugh Guiney :

Какие коды ключей проверяются:

  • 95, <106 соответствует цифровой клавиатуре от 0 до 9;
  • 47, <58 соответствует от 0 до 9 в строке чисел; и 8 это Backspace.

Таким образом, этот скрипт предотвращает ввод неверного ключа при вводе.


20
Проголосовано, но я думаю, что это поможет уточнить, какие коды клавиш проверяются:> 95, <106 соответствует цифровой клавиатуре от 0 до 9; > 47, <58 соответствует 0-9 в строке чисел; и 8 это Backspace. Таким образом, этот скрипт не позволяет вводить какие-либо ключи, кроме тех, которые введены. Это тщательно, но я думаю, что это может быть излишним для браузеров, которые изначально поддерживают ввод чисел, которые уже отфильтровывают буквенные клавиши (за исключением символов, таких как «е», которые могут иметь числовое значение). Вероятно, было бы достаточно предотвратить 189 (тире) и 109 (вычесть). А затем объединить с min="0".
Хью Гиней

1
@Manwal Ограничивает копирование и вставку чисел с помощью клавиатуры. И позволяет мне копировать вставить отрицательные числа с помощью мыши.
Бенитон

1
@Beniton Спасибо, давая этот вариант использования. Можете ли вы дать мне небольшое представление о том, что вы делаете. Всегда я могу вам помочь. Пожалуйста, предоставьте небольшой исполняемый код или скрипку. Вы можете иметь форму подтверждения уровня отправки в вашем коде. Хотя у меня всегда есть проверка в Backend, если я не разрешаю отрицательные числа.
Манвал

1
Просто скопируйте и вставьте в поле в основном. Это не совсем особый случай или что-то в этом роде. Вместо того, чтобы обрабатывать проверку с помощью ключевого кода, вероятно, лучше сделать это с помощью onChange или focusOut и создать небольшую функцию проверки для отлова любых отрицательных чисел.
ulisesrmzroche

1
Условие для клавиши со стрелкой (37, 38, 39, 41) также должно быть поставлено. || (e.keyCode>36 && e.keyCode<41)Это не позволяет пользователю увеличивать / уменьшать число с помощью стрелок вверх / вниз и идти вправо / влево для редактирования номера.
Вусан

86

Для меня решение было:

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

1
Действительно лучшее решение, если вы используете pattern и noformvalidate с angular, поскольку модель не обновляется, если не находится в пределах диапазона. Мой случай:<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) ">
Себиус

это работает лучше всего, когда пользователь знает, что значение по умолчанию равно 0. Другой мудрый пользователь запутается при нажатии на клавишу возврата, почему поле не очищается. Кроме этого, это лучшее решение. + 1
Deep 3015

1
ты спас мой день
stackmalux

Это работает лучше всего, и в случае использования десятичной также. Я использовал другой ответ выше, он перестал работать, когда разрешен десятичный. Есть ли способ, которым мы можем переместить этот ответ так, чтобы люди могли использовать это в основном.
Субхан Ахмед

31

Этот код работает нормально для меня. Можете ли вы проверить:

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

2
Это работает, но очистка всего ввода после того, как вы попытаетесь напечатать -, не очень хорошая идея.
расширенный

9
@extempl Звучит как справедливое наказание для пользователя, пытающегося ввести отрицание в поле, где здравый смысл указывает, что отрицаний нет.
Хофи

3
<input type="number" name="test" min="0" oninput="validity.valid||(value=value.replace(/\D+/g, ''))">- это удалит все нецифровые символы
Олег Мельник

@Rexford Я согласен, но я поставил, min="0"так что нет никаких отрицательных. Если вы хотите получить отрицательное значение, удалите этот атрибут.
Chinmay235

1
Я попробовал это, но это также предотвратило ввод чисел с десятичными точками.
Клент

21

Простой метод:

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


Красиво и легко ... но все же, отрицательные числа могут быть вставлены.
Ральф

10

Я хотел разрешить десятичные числа и не очистить весь ввод, если был введен отрицательный. Это хорошо работает в Chrome, по крайней мере:

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

Как можно добавить еще номер ASCII здесь. например, с 45 я хочу добавить 46 также. Как это можно сделать?
Прадип Сингх

3
@PradeepSingh "return [45, 46] .indexOf (event.charCode) == -1"
Икей говорит восстановить Монику

Пожалуйста, подумайте из коробки. Вы действительно уверены, что это keypressединственный способ ввести отрицательное число во входные данные ...
Roko C. Buljan

6

Ответ @Manwal хорош, но мне нравится код с меньшим количеством строк кода для лучшей читабельности. Также мне нравится использовать onclick / onkeypress в html.

Мое предлагаемое решение делает то же самое: Добавить

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

на ввод HTML и

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

как функция JavaScript.

Как сказано, он делает то же самое. Это просто личное предпочтение в том, как решить проблему.


5

Просто для справки: с помощью jQuery вы можете перезаписывать отрицательные значения в focusout с помощью следующего кода:

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

Это не заменяет проверку на стороне сервера!


Это работает нормально, если пользователь фокусируется вне поля ввода, однако, если они сразу же нажимают клавишу ввода, оставаясь в поле; они все еще могут ввести отрицательное число.
NemyaNation

3

Вот угловое 2 решение:

создать класс 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();
    }
  }
}

добавьте OnlyNumber к объявлениям в app.module.ts и используйте его в любом месте вашего приложения

<input OnlyNumber="true">

Есть ли способ разрешить вставку для этого? Кроме того, я изменил регулярное выражение на: /^-?[0-9]+(\.[0-9]*)‹0,1‹$/g, чтобы разрешить отрицательные числа, но, похоже, это не работает?
Дейв Ноттаж

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

2
Хотя этот фрагмент кода может решить вопрос, в том числе объяснение действительно помогает улучшить качество вашего сообщения. Помните, что вы отвечаете на вопрос читателей в будущем, и эти люди могут не знать причин, по которым вы предлагаете код.
Судхиш Синганамалла

Хотя это может быть правильным ответом, в нем недостаточно подробностей. Объясните пожалуйста почему это работает. При использовании переполнения стека учитывайте, что это живая база знаний , ответы, которые не делятся знаниями, гораздо менее полезны.
Marc LaFleur

2

Просто добавьте еще один способ сделать это (используя Angular), если вы не хотите портить HTML еще большим количеством кода:

Вам нужно только подписаться на поле valueChanges и установить значение как абсолютное значение. (заботясь о том, чтобы не генерировать новое событие, поскольку это вызовет другое значение valueChange, а следовательно, рекурсивный вызов и вызовет ошибку превышения максимального размера вызова)

HTML-код

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

КОД TypeScript (внутри вашего компонента)

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

Ответ на это не полезен. поскольку он работает только при использовании клавиш вверх / вниз, но если вы введете -11, он не будет работать. Итак, вот небольшое исправление, которое я использую

этот для целых

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

этот, когда у вас есть номера цены

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

Это решение позволяет использовать все функции клавиатуры, включая копирование и вставку с клавиатуры. Это предотвращает вставку отрицательных чисел с помощью мыши. Работает со всеми браузерами и демо на codepen использует bootstrap и jQuery. Это должно работать с неанглийскими настройками и клавиатурой. Если браузер не поддерживает захват события вставки (IE), он удалит отрицательный знак после фокусировки. Это решение ведет себя так, как должен работать нативный браузер с min = 0 type = number.

Разметка:

<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

Вот решение, которое работает лучше всего для поля QTY, которое допускает только числа.

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.