Недавно у нас появился повод переработать то, как мы собираем даты рождения (и другие даты в Серафине). Хотя поначалу реализация браузера по умолчанию могла помочь, мы столкнулись с несколькими проблемами:

  1. Реализация не одинакова во всех браузерах.
  2. Большинство браузеров открывали ввод календаря с упором на сегодняшнюю дату, из-за чего нашим пользователям было сложно вводить дату своего рождения.

Мы решили создать наш компонент ввода даты, чтобы исправить это (используя Vue.js).

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

Следовательно, в этой серии вы находитесь в первой статье, демонстрирующей мой пользовательский компонент даты в Vue.js. Во второй части мы рассмотрим, как создать такой же компонент в ванильном javascript, и закончим серию их сравнением.

Спецификации

Спецификации для нашего компонента DateInput должны вести себя как собственные входные данные даты в браузерах за вычетом выбора календаря, то есть:

  • Мы можем ввести только две цифры для дня и месяца.
  • Мы можем ввести только четыре цифры года.
  • День должен быть между 1 и 31
  • Месяц должен быть между 1 и 12
  • Год должен быть между 1900 и 2100 (это на нас, а не на браузере)
  • Нам нужно вводить даты, либо вводя цифры напрямую, либо перемещаясь вверх и вниз с помощью клавиш со стрелками.
  • Если мы вводим даты с помощью клавиш со стрелками и достигаем верхнего или нижнего пределов, отображаемое число должно зацикливаться.
  • Если мы вводим даты, набирая числа, ввод должен быть привязан к марже (max(input, highMargin) или min (input, lowerMargin)
  • Мы должны интуитивно направить пользователя к следующему полю.
  • Мы должны проверить правильность даты.

Компонент DateInput в Vue.js

Вот код DateInput (Вы также можете найти его здесь). Вы должны иметь возможность скопировать-вставить его и использовать как есть :)

Сосредоточьтесь на ключевых элементах:

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

Каждый из трех входов будет иметь два пути:

приращение {День|Месяц|Год} (ключ)

Доступ к этому пути осуществляется при использовании клавиш со стрелками и будет:

  1. увеличить или уменьшить значение на единицу в зависимости от того, какую клавишу со стрелкой вы нажимаете.

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

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

handle{День|Месяц|Год} (значение)

Как вы видите, все становится сложнее, когда пользователь вводит значение даты, вводя числа. Разбираем происходящее:

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

2. Если значение дня больше трех или значение месяца больше 1 (и значения достаточно длинные), мы устанавливаем флаг для перехода к следующему полю в конце.

3. Мы форматируем значение, чтобы оно содержало правильные цифры.

4. Проверяем наличие ошибок в поле.

5. Переходим к следующему полю, если обсуждавшийся ранее флаг истинен.

Проверка ошибок

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

Вы могли бы подумать, что `new Date('30-02-1990') будет вести себя последовательно между браузерами, но вы ошибаетесь.

Существует несоответствие, по крайней мере, между Firefox и Chrome.

// Firefox =>
new Date(‘30–02–1990’) => Error Date Invalid
// Chrome
new Date(‘30–02–1990’) => 02/03/1990

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

Короче говоря, если дата вызывает исключение, мы возвращаем true для ошибки. И если дата не выбрасывает исключение, мы проверяем, совпадают ли дни.

Должен ли я использовать это?

Если вы используете Vue.js и не хотите импортировать причудливую библиотеку выбора даты или просто хотите ввести данные без возможности для пользователей использовать средство выбора даты, это достаточно просто реализовать и интуитивно понятно в использовании.

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

Заключение

Создание пользовательского компонента даты в Vue.js достаточно сложно, но в конечном итоге достаточно просто (на реализацию у нас ушло около 3–4 дней, и большую часть времени мы потратили на выяснение спецификаций и рефакторинг нашего кода.

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

Оставайтесь с нами, чтобы не пропустить вторую часть, и подпишитесь на @pcurell в Твиттере, чтобы узнать, когда я ее выпущу :)

Больше контента на plainenglish.io. Подпишитесь на нашу бесплатную еженедельную рассылку здесь.