Проверка числового ввода при форматировании числового ввода

В проекте asp.net-mvc с использованием С#.

Я использую функцию для форматирования больших чисел запятыми, например 1,000,000, благодаря этой записи:

function numberWithCommas(str) {
    return str.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}

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

<input type="number" min="0" class="myclass" value="@somevalue" />

Это создает проблему с использованием JS, поскольку для этого требуется только ввод номера. Что вызывает меня на такой вопрос Как сделать HTML-тег только принимать числовые значения?, который также предлагает решение JS.

Мне интересно, если кто-то разработал элегантный способ форматирования числового ввода, а при проверке числового ввода, есть ли какие-либо другие варианты, доступные здесь? Это не обязательно должно быть JS-решением.

Ответы

Ответ 1

Вы не можете использовать числовой ввод, потому что, ну, JavaScript не считает отформатированное число числом.

Опция заключается в использовании нечислового ввода, но отфильтруйте любые "проблемные" символы.

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

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

function format(inp){
  var start = inp.selectionStart,  // get the selection start
      end   = inp.selectionEnd;    // and end, as per the linked post
  var s1=inp.value.split(",").length-1; //count the commas before edit
  inp.value=numberWithCommas(inp.value.replace(/,|[^\d.]/g,''));
  var s2=inp.value.split(",").length-s1-1; //count the commas after edit so as to know where to place the cursor, as the position changes, if there are new commas or some commas have been removed
  inp.setSelectionRange(start+s2, end+s2); // set the selection start and end, as per the linked post
}
function numberWithCommas(str) {
  var a=str.split('.');
  var p=/\B(?=(\d{3})+(?!\d))/g;
  if(a.length>1)
    return a[0].toString().replace(p, ",")+"."+a[1];
  else 
    return str.toString().replace(p, ",");
}
<input onkeyup="format(this)">

Ответ 2

У меня есть ответ на ваш первый вопрос.

Вы можете отключить все ключи, а не только клавиши с номерами.

function isNumberKey(evt)  {
    var charCode = (evt.which) ? evt.which : event.keyCode;

    if (charCode != 43 && charCode > 31
      && (charCode < 48 || charCode > 57))
        return false;
    return true;

}

Я также создал рабочую демонстрацию на jsfiddle

Ответ 3

Поток программы:
Получение ввода через событие on change и вызов других функций, показывающих передачу данных через POST Ajax.

$('.Amount').on("change", function (e) {
    var myInput = $(e.target);
    var input = this.value;
    // Remove any non digits (including commas) to pass value to controller.
    var Amount = validateInput(input);
    // Format the string to have commas every three digits 1,000,000 for display.
    var val = numberWithCommas(Amount);
    $(myInput).val(val);

    $.ajax({
        type: 'POST',
        dataType: "json",
        url: somesUrl + '/' + somethingelse,
        data: JSON.parse('{"Amount": "' + Amount + '"}'), // Amount is a nice format here and will not throw an error.
        // TODO etc
    });
});

Удалите любые ненулевые числа и укажите значение нуля, если никакие номера не введены.

var validateInput = function (input) {
    input = input.toString().replace(/[^0-9]/g, "");
    /* Remove leading zeros. */
    input = input.replace(/^0+/, '');
    if (input == "")
        input = 0;
    return input;
}

Отформатируйте ввод с запятыми 1 000 000 000.

function numberWithCommas(str) {
    return str.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}

Таким образом, даже если пользователь вводит ввод с запятыми, например. 1,734,567 он будет работать, и если они ошибаются, где они помещают запятую, например. 17,35,555 он все равно будет проверять.

Смотрите рабочий скрипт.

Я на самом деле разработал хорошее решение, пытаясь выполнить сроки проекта, и отчасти это было решено этим ответом nicael.

Это решение не проверяет ввод, когда он набирается, но после его завершения я выбрал событие изменения, в отличие от события ввода, поскольку он вызывает функцию один раз и (аналогично событию отправки), чем проверяет ввод в одном вызове. Удаление любых запятых и цифр; решая проблему форматирования запятыми, удаляя их для вызова ajax, затем переформатируя его запятыми для отображения. Существует проверка удаления ведущих нулей.

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