jQuery: каков наилучший способ ограничить "числовой" ввод только для текстовых полей? (разрешить десятичные точки)

Каков наилучший способ ограничить "числовой" ввод только для текстовых полей?

Я ищу то, что позволяет десятичные точки.

Я вижу много примеров. Но еще предстоит решить, какой из них использовать.

Обновление от Правин Джеганатан

Больше никаких плагинов, JQuery реализовал свой собственный jQuery.isNumeric() добавлено в v1.7. Смотрите: /questions/5069413/jquery-kakov-nailuchshij-sposob-ogranichit-chislovoj-vvod-tolko-dlya-tekstovyih-polej-razreshit-desyatichnyie-tochki/5069424#5069424

40 ответов

Решение

Обновить

Для этого есть новое и очень простое решение:

Это позволяет использовать любой вид фильтра ввода текста <input>, включая различные числовые фильтры. Это будет правильно обрабатывать Copy+Paste, Drag+Drop, сочетания клавиш, операции с контекстным меню, неиспользуемые клавиши и все раскладки клавиатуры.

Посмотрите этот ответ или попробуйте сами на JSFiddle.

jquery.numeric плагин

Я успешно реализовал много форм с помощью плагина jquery.numeric.

$(document).ready(function(){
    $(".numeric").numeric();
});

Кроме того, это работает и с textareas!

Однако обратите внимание, что Ctrl+A, Copy+Paste (через контекстное меню) и Drag + Drop не будут работать должным образом.

HTML 5

Благодаря более широкой поддержке стандарта HTML 5 мы можем использовать pattern атрибут и number тип для input элементы, ограничивающие только ввод числа. В некоторых браузерах (в частности, в Google Chrome) он также позволяет ограничивать вставку нечислового содержимого. Больше информации о number и другие новые типы ввода доступны здесь.

Если вы хотите ограничить ввод (в отличие от проверки), вы можете работать с ключевыми событиями. что-то вроде этого:

<input type="text" class="numbersOnly" value="" />

А также:

jQuery('.numbersOnly').keyup(function () { 
    this.value = this.value.replace(/[^0-9\.]/g,'');
});

Это сразу дает пользователю знать, что он не может вводить буквенные символы и т. Д., А не позже, на этапе проверки.

Вы все равно захотите проверить, потому что ввод может быть заполнен путем вырезания и вставки мышью или, возможно, автозаполнением формы, которое может не вызывать ключевые события.

Я думал, что лучшим ответом был тот, что выше, чтобы просто сделать это.

jQuery('.numbersOnly').keyup(function () {  
    this.value = this.value.replace(/[^0-9\.]/g,''); 
});

но я согласен, что немного неприятно, что клавиши со стрелками и кнопка удаления привязывают курсор к концу строки (и из-за этого он был отброшен мне при тестировании)

Я добавил в простом изменении

$('.numbersOnly').keyup(function () {
    if (this.value != this.value.replace(/[^0-9\.]/g, '')) {
       this.value = this.value.replace(/[^0-9\.]/g, '');
    }
});

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

Плагин jquery.numeric содержит некоторые ошибки, о которых я уведомил автора. Он позволяет использовать несколько десятичных знаков в Safari и Opera, и вы не можете вводить клавишу Backspace, клавиши со стрелками или несколько других управляющих символов в Opera. Я нуждался в положительном целочисленном вводе, так что в итоге я просто написал свой собственный.

$(".numeric").keypress(function(event) {
  // Backspace, tab, enter, end, home, left, right
  // We don't support the del key in Opera because del == . == 46.
  var controlKeys = [8, 9, 13, 35, 36, 37, 39];
  // IE doesn't support indexOf
  var isControlKey = controlKeys.join(",").match(new RegExp(event.which));
  // Some browsers just don't raise events for control keys. Easy.
  // e.g. Safari backspace.
  if (!event.which || // Control keys in most browsers. e.g. Firefox tab is 0
      (49 <= event.which && event.which <= 57) || // Always 1 through 9
      (48 == event.which && $(this).attr("value")) || // No 0 first digit
      isControlKey) { // Opera assigns values for control keys.
    return;
  } else {
    event.preventDefault();
  }
});

Больше нет плагинов, jQuery реализовал свой собственный jQuery.isNumeric(), добавленный в v1.7.

jQuery.isNumeric( value )

Определяет, является ли его аргумент числом.

Образцы результатов

$.isNumeric( "-10" );     // true
$.isNumeric( 16 );        // true
$.isNumeric( 0xFF );      // true
$.isNumeric( "0xFF" );    // true
$.isNumeric( "8e5" );     // true (exponential notation string)
$.isNumeric( 3.1415 );    // true
$.isNumeric( +10 );       // true
$.isNumeric( 0144 );      // true (octal integer literal)
$.isNumeric( "" );        // false
$.isNumeric({});          // false (empty object)
$.isNumeric( NaN );       // false
$.isNumeric( null );      // false
$.isNumeric( true );      // false
$.isNumeric( Infinity );  // false
$.isNumeric( undefined ); // false

Вот пример того, как связать isNumeric () с прослушивателем событий

$(document).on('keyup', '.numeric-only', function(event) {
   var v = this.value;
   if($.isNumeric(v) === false) {
        //chop off the last char entered
        this.value = this.value.slice(0,-1);
   }
});

Плагин numeric(), упомянутый выше, не работает в Opera (вы не можете возвращать, удалять или даже использовать клавиши "назад" или "вперед").

Код ниже как в JQuery, так и в Javascript будет отлично работать (и это всего две строки).

JQuery:

$(document).ready(function() {
    $('.key-numeric').keypress(function(e) {
            var verified = (e.which == 8 || e.which == undefined || e.which == 0) ? null : String.fromCharCode(e.which).match(/[^0-9]/);
            if (verified) {e.preventDefault();}
    });
});

Javascript:

function isNumeric(e)
{
    var keynum = (!window.event) ? e.which : e.keyCode;
    return !((keynum == 8 || keynum == undefined || e.which == 0) ? null : String.fromCharCode(keynum).match(/[^0-9]/));
}

Конечно, это только для чисто числового ввода (плюс клавиши "backspace", "delete", "вперед / назад"), но его можно легко изменить, добавив точки и минус символы.

Вы можете использовать плагин Validation с его методом number().

$("#myform").validate({
  rules: {
    field: {
      required: true,
      number: true
    }
  }
});

Нет необходимости в длинном коде для ограничения ввода чисел, просто попробуйте этот код.

Он также принимает действительные значения int и float для обоих значений.

Javascript Подход

onload =function(){ 
  var ele = document.querySelectorAll('.number-only')[0];
  ele.onkeypress = function(e) {
     if(isNaN(this.value+""+String.fromCharCode(e.charCode)))
        return false;
  }
  ele.onpaste = function(e){
     e.preventDefault();
  }
}
<p> Input box that accepts only valid int and float values.</p>
<input class="number-only" type=text />

JQuery подход

$(function(){

  $('.number-only').keypress(function(e) {
 if(isNaN(this.value+""+String.fromCharCode(e.charCode))) return false;
  })
  .on("cut copy paste",function(e){
 e.preventDefault();
  });

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p> Input box that accepts only valid int and float values.</p>
<input class="number-only" type=text />

ОБНОВИТЬ

Приведенные выше ответы предназначены для наиболее распространенного варианта использования - проверки ввода в виде числа.

Но ниже приведен фрагмент кода для особых случаев использования

  • Разрешение отрицательных чисел
  • Отображение неверного нажатия клавиши перед его удалением.

$(function(){
      
  $('.number-only').keyup(function(e) {
        if(this.value!='-')
          while(isNaN(this.value))
            this.value = this.value.split('').reverse().join('').replace(/[\D]/i,'')
                                   .split('').reverse().join('');
    })
    .on("cut copy paste",function(e){
     e.preventDefault();
    });

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p> Input box that accepts only valid int and float values.</p>
<input class="number-only" type=text />

Ниже приводится то, что я использую, чтобы буквально блокировать нажатия клавиш. Это позволяет только цифры 0-9 и десятичную точку. Легко реализовать, не много кода и работает как шарм:

<script>
function isNumberKey(evt) {
    var charCode = (evt.which) ? evt.which : event.keyCode;
    if (charCode != 46 && charCode > 31 && (charCode < 48 || charCode > 57)) {
        return false;
    } else {
        return true;
    }      
}
</script>

<input value="" onkeypress="return isNumberKey(event)">

В качестве небольшого улучшения этого предложения вы можете использовать плагин Validation с его методами number (), цифрами и диапазоном. Например, следующее гарантирует, что вы получите положительное целое число от 0 до 50:

$("#myform").validate({
  rules: {
    field: {
      required: true,
      number: true,
      digits: true,
      range : [0, 50]
    }
  }
});

Вы не видите магическое появление и исчезновение алфавитов при нажатии клавиш. Это работает и на мышиную пасту.

$('#txtInt').bind('input propertychange', function () {
    $(this).val($(this).val().replace(/[^0-9]/g, ''));
});

Сначала я попытался решить эту проблему с помощью jQuery, но меня не порадовали нежелательные символы (не цифры), которые фактически появляются в поле ввода перед удалением из keyup.

В поисках других решений я нашел это:

Целые числа (неотрицательные)

<script>
  function numbersOnly(oToCheckField, oKeyEvent) {
    return oKeyEvent.charCode === 0 ||
        /\d/.test(String.fromCharCode(oKeyEvent.charCode));
  }
</script>

<form name="myForm">
<p>Enter numbers only: <input type="text" name="myInput" 
    onkeypress="return numbersOnly(this, event);" 
    onpaste="return false;" /></p>
</form>

Источник: https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers.onkeypress Живой пример: http://jsfiddle.net/u8sZq/

Десятичные точки (неотрицательные)

Чтобы разрешить одну десятичную точку, вы можете сделать что-то вроде этого:

<script>
  function numbersOnly(oToCheckField, oKeyEvent) {        
    var s = String.fromCharCode(oKeyEvent.charCode);
    var containsDecimalPoint = /\./.test(oToCheckField.value);
    return oKeyEvent.charCode === 0 || /\d/.test(s) || 
        /\./.test(s) && !containsDecimalPoint;
  }
</script>

Источник: Просто написал это. Кажется, работает. Живой пример: http://jsfiddle.net/tjBsF/

Другие настройки

  • Чтобы разрешить ввод большего количества символов, просто добавьте их к регулярному выражению, действующему в качестве основного фильтра кода символа.
  • Чтобы реализовать простые контекстные ограничения, посмотрите на текущее содержимое (состояние) поля ввода (oToCheckField.value)

Некоторые вещи, которые могут вас заинтересовать:

  • Допускается только одна десятичная точка
  • Разрешить знак минус можно только в том случае, если он расположен в начале строки. Это позволило бы для отрицательных чисел.

Упущения

  • Положение каретки не доступно внутри функции. Это значительно уменьшило контекстные ограничения, которые вы можете реализовать (например, нет двух одинаковых последовательных символов). Не уверен, что лучший способ получить к нему доступ.

Я знаю, что заголовок запрашивает решения jQuery, но, надеюсь, кто-нибудь найдет это полезным в любом случае.

Спасибо за пост Дейва Аарона Смита

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

$(".numeric").keypress(function(event) {
  // Backspace, tab, enter, end, home, left, right,decimal(.)in number part, decimal(.) in alphabet
  // We don't support the del key in Opera because del == . == 46.
  var controlKeys = [8, 9, 13, 35, 36, 37, 39,110,190];
  // IE doesn't support indexOf
  var isControlKey = controlKeys.join(",").match(new RegExp(event.which));
  // Some browsers just don't raise events for control keys. Easy.
  // e.g. Safari backspace.
  if (!event.which || // Control keys in most browsers. e.g. Firefox tab is 0
      (49 <= event.which && event.which <= 57) || // Always 1 through 9
      (96 <= event.which && event.which <= 106) || // Always 1 through 9 from number section 
      (48 == event.which && $(this).attr("value")) || // No 0 first digit
      (96 == event.which && $(this).attr("value")) || // No 0 first digit from number section
      isControlKey) { // Opera assigns values for control keys.
    return;
  } else {
    event.preventDefault();
  }
});
   window.jQuery.fn.ForceNumericOnly =
       function () {

           return this.each(function () {
               $(this).keydown(function (event) {
                   // Allow: backspace, delete, tab, escape, and enter
                   if (event.keyCode == 46 || event.keyCode == 8 || event.keyCode == 9 || event.keyCode == 27 || event.keyCode == 13 ||
                       // Allow: Ctrl+A
                       (event.keyCode == 65 && event.ctrlKey === true) ||
                       // Allow: home, end, left, right
                       (event.keyCode >= 35 && event.keyCode <= 39)) {
                       // let it happen, don't do anything
                       return;
                   } else {
                       // Ensure that it is a number and stop the keypress
                       if (event.shiftKey || (event.keyCode < 48 || event.keyCode > 57) && (event.keyCode < 96 || event.keyCode > 105)) {
                           event.preventDefault();
                       }
                   }
               });
           });
       };

И примените это ко всем входам, которые вы хотите:

$('selector').ForceNumericOnly();

HTML5 поддерживает номер типа ввода с глобальной поддержкой браузеров 88%+ согласно CanIUse по состоянию на октябрь 2015 года.

<input type="number" step="0.01" min="0" name="askedPrice" id="askedPrice" />

Это не связано с JQuery, но преимущество в том, что на мобильных телефонах клавиатура Android будет оптимизирована для ввода цифр.

В качестве альтернативы можно использовать тип ввода текста с новым параметром "шаблон". Больше подробностей в спецификации HTML5.

Я думаю, что это лучше, чем решение jquery, так как в данном вопросе решение jquery не поддерживает разделитель тысяч. Если вы можете использовать HTML5.

JSFiddle: https://jsfiddle.net/p1ue8qxj/

Эта функция делает то же самое, использует некоторые идеи выше.

$field.keyup(function(){
    var val = $j(this).val();
    if(isNaN(val)){
         val = val.replace(/[^0-9\.]/g,'');
         if(val.split('.').length>2) val =val.replace(/\.+$/,"");
    }
    $j(this).val(val); 
});
  • показать визуальную обратную связь (перед исчезновением появляется неправильное письмо)
  • позволяет десятичные
  • ловит несколько "."
  • не имеет проблем с левым / правым делом и т. д.

/* это моя кросс-браузерная версия Как разрешить только числовые (0-9) в поле ввода HTML, используя jQuery?
* /

$("#inputPrice").keydown(function(e){
    var keyPressed;
    if (!e) var e = window.event;
    if (e.keyCode) keyPressed = e.keyCode;
    else if (e.which) keyPressed = e.which;
    var hasDecimalPoint = (($(this).val().split('.').length-1)>0);
    if ( keyPressed == 46 || keyPressed == 8 ||((keyPressed == 190||keyPressed == 110)&&(!hasDecimalPoint && !e.shiftKey)) || keyPressed == 9 || keyPressed == 27 || keyPressed == 13 ||
             // Allow: Ctrl+A
            (keyPressed == 65 && e.ctrlKey === true) ||
             // Allow: home, end, left, right
            (keyPressed >= 35 && keyPressed <= 39)) {
                 // let it happen, don't do anything
                 return;
        }
        else {
            // Ensure that it is a number and stop the keypress
            if (e.shiftKey || (keyPressed < 48 || keyPressed > 57) && (keyPressed < 96 || keyPressed > 105 )) {
                e.preventDefault();
            }
        }

  });

Вы можете использовать autoNumeric от decorplanit.com. У них есть хорошая поддержка числовых, а также валюты, округления и т. Д.

Я использовал в среде IE6, с некоторыми изменениями CSS, и это был разумный успех.

Например, класс CSS numericInput может быть определено, и это может быть использовано для украшения ваших полей с числовыми масками ввода.

адаптировано с сайта autoNumeric:

$('input.numericInput').autoNumeric({aSep: '.', aDec: ','}); // very flexible!

Я думаю, что это хороший способ решения этой проблемы, и он чрезвычайно прост:

$(function() {
    var pastValue, pastSelectionStart, pastSelectionEnd;

    $("input").on("keydown", function() {
        pastValue          = this.value;
        pastSelectionStart = this.selectionStart;
        pastSelectionEnd   = this.selectionEnd;
    }).on("input propertychange", function() {
        var regex = /^[0-9]+\.?[0-9]*$/;

        if (this.value.length > 0 && !regex.test(this.value)) {
            this.value          = pastValue;
            this.selectionStart = pastSelectionStart;
            this.selectionEnd   = pastSelectionEnd;
        }
    });
});

Пример: JSFiddle

Сценарии покрыты

Большинство подобных рекомендаций здесь не соответствуют хотя бы одному из них или требуют много кода для охвата всех этих сценариев.

  1. Допускается только 1 десятичная точка.
  2. Позволяет home, endи arrow ключи.
  3. Позволяет delete а также backspace использоваться для любого индекса.
  4. Позволяет редактировать по любому индексу (при условии, что входные данные соответствуют регулярному выражению).
  5. Позволяет Ctrl+ V и Shift + Вставка для правильного ввода (то же самое с правой кнопкой мыши + вставить).
  6. Не мерцает текстовое значение, потому что keyup событие не используется.
  7. Восстанавливает выбор после неверного ввода.

Сценарии провалились

  • Начиная с 0.5 и удаление только ноля не будет работать. Это можно исправить, изменив регулярное выражение на /^[0-9]*\.?[0-9]*$/ а затем добавить событие размытия, чтобы добавить 0 когда текстовое поле начинается с десятичной точки (при желании). Посмотрите этот продвинутый сценарий, чтобы лучше понять, как это исправить.

Plugin

Я создал этот простой плагин jquery, чтобы сделать это проще:

$("input").limitRegex(/^[0-9]+\.?[0-9]*$/);

Просто запустите содержимое через parseFloat(). Он вернется NaN на неверный ввод.

Если вы используете HTML5, вам не нужно идти на все, чтобы выполнить проверку. Просто используйте -

<input type="number" step="any" />

Атрибут шага позволяет использовать десятичную точку.

Другой способ сохранить позицию каретки на входе:

$(document).ready(function() {
  $('.numbersOnly').on('input', function() {
    var position = this.selectionStart - 1;

    fixed = this.value.replace(/[^0-9\.]/g, '');  //remove all but number and .
    if(fixed.charAt(0) === '.')                  //can't start with .
      fixed = fixed.slice(1);

    var pos = fixed.indexOf(".") + 1;
    if(pos >= 0)
      fixed = fixed.substr(0,pos) + fixed.slice(pos).replace('.', '');  //avoid more than one .

    if (this.value !== fixed) {
      this.value = fixed;
      this.selectionStart = position;
      this.selectionEnd = position;
    }
  });
});

Преимущества:

  1. Пользователь может использовать клавиши со стрелками, Backspace, Delete, ...
  2. Работает, когда вы хотите вставить цифры

Плункер: Демо работает

Это фрагмент, который я только что сделал (используя часть кода Питера Мортенсена / Кейта Бентрупа) для проверки целочисленного процента в текстовом поле (требуется jQuery):

/* This validates that the value of the text box corresponds
 * to a percentage expressed as an integer between 1 and 100,
 * otherwise adjust the text box value for this condition is met. */
$("[id*='percent_textfield']").keyup(function(e){
    if (!isNaN(parseInt(this.value,10))) {
        this.value = parseInt(this.value);
    } else {
        this.value = 0;
    }
    this.value = this.value.replace(/[^0-9]/g, '');
    if (parseInt(this.value,10) > 100) {
        this.value = 100;
        return;
    }
});

Этот код:

  • Позволяет использовать основные цифровые клавиши и цифровую клавиатуру.
  • Проверяет, чтобы исключить сдвигово-числовые символы (например, #, $, % и т. Д.)
  • Заменяет значения NaN на 0
  • Заменяет на 100 значений выше 100

Я надеюсь, что это помогает нуждающимся.

Нашел отличное решение здесь http://ajax911.com/numbers-numeric-field-jquery/

Я просто изменил "keyup" на "keydown" согласно моему требованию

Лучший способ - проверить контекст текстового поля всякий раз, когда оно теряет фокус.

Вы можете проверить, является ли содержимое "числом", используя регулярное выражение.

Или вы можете использовать плагин проверки, который в основном делает это автоматически.

Проверьте этот код поиска для использования базы данных:

function numonly(root){
    >>var reet = root.value;
    var arr1 = reet.length;
    var ruut = reet.charAt(arr1-1);
    >>>if (reet.length > 0){
        var regex = /[0-9]|\./;
        if (!ruut.match(regex)){
            var reet = reet.slice(0, -1);
            $(root).val(reet);
        >>>>}
    }
}
//Then use the even handler onkeyup='numonly(this)'

Я использовал это, с хорошими результатами..

ini=$("#id").val();
a=0;
$("#id").keyup(function(e){
    var charcode = (e.which) ? e.which : e.keyCode;
    // for decimal point
    if(!(charcode===190 || charcode===110))
    {           // for numeric keys andcontrol keys
        if (!((charcode>=33 && charcode<=57) || 
        // for numpad numeric keys
        (charcode>=96 && charcode<=105) 
        // for backspace
        || charcode==8)) 
        {
            alert("Sorry! Only numeric values allowed.");
            $("#id").val(ini);
        }
        // to include decimal point if first one has been deleted.
        if(charcode===8)
        {
            ini=ini.split("").reverse();
            if(ini[0]==".")
            a=0;                 
        }
    }
    else
    {
        if(a==1)
        {
            alert("Sorry! Second decimal point not allowed.");
            $("#id").val(ini);
        }
        a=1;
    }
    ini=$("#id").val();
});


find keycodes at http://www.cambiaresearch.com/articles/15/javascript-char-codes-key-codes

Использование события нажатия клавиш

  1. Метод массива
var asciiCodeOfNumbers = [48, 49, 50, 51, 52, 53, 54, 54, 55, 56, 57]
$(".numbersOnly").keypress(function (e) {
        if ($.inArray(e.which, asciiCodeOfNumbers) == -1)
            e.preventDefault();
    });
  1. Прямой метод
$(".numbersOnly").keypress(function (e) {
        if (e.which < 48 || 57 < e.which)
            e.preventDefault();
    });

Это очень просто, так как у нас уже есть встроенная функция javascript "isNaN".

$("#numeric").keydown(function(e){
  if (isNaN(String.fromCharCode(e.which))){ 
    return false; 
  }
});

Плагин jquery.numeric хорошо работает и для меня.

Единственное, что мне не нравится, связано с интуитивностью. Нажатие клавиш "запрещается" без обратной связи с пользователем, который может стать параноиком или задаться вопросом, не сломана ли его клавиатура.

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

$('#someInput').numeric(
    null, // default config
    null, // no validation onblur callback
    function(){
        // for every blocked keypress:
        $(this).effect("pulsate", { times:2 }, 100);
    }
);

Просто пример (используя jQuery UI), конечно. Любая простая визуальная обратная связь поможет.

Другие вопросы по тегам