Попытка проверить ввод даты с помощью регулярного выражения javascript в качестве пользовательских типов - PullRequest
2 голосов
/ 17 июня 2019

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

У меня есть демо-версия с голыми костями http://jsfiddle.net/7d82j0ky/2/ где, если вы введете следующие даты:

  • 05/24/1972 (действительный)
  • 05/24/2020 (недействительный год в этом случае, текущий год - это то, где мы макс.out at)
  • 05/32/1972 (в этом случае недопустимый день)

Регулярное выражение работает, но оно недействительно, пока вы не введете полный формат даты MM /DD / YYYY.Если вы откроете консоль браузера, вы увидите, что она выводит сообщения при вводе.

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

  • 05/24 будет в порядке, так как вы вводите
  • 05/32 не будет в порядкеэти два не должны появляться в пользовательском интерфейсе, предотвращая поведение по умолчанию для этого ключевого события, поэтому вы увидите только «05/3» в текстовом поле при вводе
  • 0a не будет в порядке, каквыше «а» следует запретить, чтобы при вводе текста вы видели только «0».

Каков наилучший способ сопоставления регулярному выражению при вводе?

У меня есть несколько тестов для регулярного выражения даты здесь https://regex101.com/r/M8habw/1/, и все они, кажется, работают нормально, основываясь на датах, которые нам нужны в приложении.Я не супер адепт в regex, но этот не такой уж и сложный.

Вот код jsfiddle, который можно разместить здесь:

<input class="input" type="text" maxlength="10" placeholder="MM/DD/YYYY"/>

$('.input').on('input', function(e) {
    var regex = /^(0[1-9]|1[0-2])\/(0[1-9]|1\d|2\d|3[01])\/((19[2-9]\d{1})|20[0|1]\d{1})$/g;

    if (!this.value.match(regex)) {
        console.log('nope');
        e.preventDefault();
    } else {
        console.log('yep');
    }
});

1 Ответ

0 голосов
/ 28 июня 2019

Вы не можете подтвердить дату только с помощью регулярного выражения.Или, по крайней мере, не разумный.Для этого было бы достаточно продвинуться в високосные годы и т.д.В вашей функции oninput вы можете удалить нецифровые символы, работать со строкой цифр (убедитесь, что это правильная дата) и добавлять только другие символы («символы форматирования») туда, где они должны быть после этого.

Если у вас есть неполная дата в формате MMDDYYYY (но возможно заполнение только некоторыми символами), и вы хотите убедиться, что это не может привести к недопустимой дате, у вас может быть функция, подобная приведенной ниже.
Одна хитрость заключается в том, что создание недопустимой даты в Javascript не всегда будет давать недопустимый результат, оно будет просто переполнено, поэтому 2019-01-32 даст вам дату для 2019-02-01.Хотя это полезно в некоторых случаях, это раздражает нас, так как мы пытаемся обнаружить недопустимые даты.Но тогда мы можем убедиться, что строка, представляющая сгенерированную дату, совпадает с той, которую мы предоставили.Если это не так, мы находимся в случае «переполнения».

function hasErrors(val) {
    let month = val.slice(0, 2);
    let day = val.slice(2, 4);
    let year = val.slice(4);
    // The string is fully empty - not an invalid input
    if (!month.length) {
        return false;
    }
    // Only one of the months digits is filled out. Assume the rest will be filled out by the smallest possible valid value
    //   (optimistic heuristic)
    if (month.length === 1) {
        month += month === '0' ? '1' : '0';
    }
    // Invalid month
    if (+month > 12 || +month <= 0) {
        return true;
    }
    // Month valid but day not filled - ok
    if (!day.length) {
        return false;
    }
    // Only part of the day filled, same as above with the month
    if (day.length === 1) {
        day += day === '0' ? '1' : '0';
    }
    // Days always invalid
    if (+day > 31 || +day <= 0) {
        return true;
    }
    // If the year is not fully filled out, use any year with a 29 Feb
    if (year.length < 4) {
        year = '1972';
    }
    // Make sure the date is valid (e.g. no 31st of April)
    let sourceStr = [year, month, day].join('-');
    let date = new Date(sourceStr);
    if (!+date || date.toISOString().slice(0, 10) !== sourceStr) {
        return true;
    }

    // No error was detected
    return false;
}

Вот пример скрипта .

Теперь, как уже упоминалось, UX-мудрыйдовольно плохая идея блокировать ввод пользователя.Это сбивает с толку, особенно при попытке отредактировать середину строки, а не конец.Лучшим решением было бы просто указать на ошибку с помощью стиля.Вот пример скрипта , не блокирующий пользовательский ввод (просто изменил деталь вокруг строки 76).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...