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 десятичная точка.
- Позволяет
home
,end
иarrow
ключи. - Позволяет
delete
а такжеbackspace
использоваться для любого индекса. - Позволяет редактировать по любому индексу (при условии, что входные данные соответствуют регулярному выражению).
- Позволяет Ctrl+ V и Shift + Вставка для правильного ввода (то же самое с правой кнопкой мыши + вставить).
- Не мерцает текстовое значение, потому что
keyup
событие не используется. - Восстанавливает выбор после неверного ввода.
Сценарии провалились
- Начиная с
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;
}
});
});
Преимущества:
- Пользователь может использовать клавиши со стрелками, Backspace, Delete, ...
- Работает, когда вы хотите вставить цифры
Плункер: Демо работает
Это фрагмент, который я только что сделал (используя часть кода Питера Мортенсена / Кейта Бентрупа) для проверки целочисленного процента в текстовом поле (требуется 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
Использование события нажатия клавиш
- Метод массива
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();
});
- Прямой метод
$(".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), конечно. Любая простая визуальная обратная связь поможет.