diff --git a/files/uk/web/html/element/input/date/index.md b/files/uk/web/html/element/input/date/index.md new file mode 100644 index 0000000000..f70d6b7651 --- /dev/null +++ b/files/uk/web/html/element/input/date/index.md @@ -0,0 +1,506 @@ +--- +title: +slug: Web/HTML/Element/input/date +tags: + - Date + - Date picker + - Element + - Form Inputs + - HTML + - HTML forms + - Input + - Input Element + - Input Type + - Reference +browser-compat: html.elements.input.type_date +--- + +{{HTMLRef}} + +Елементи {{HTMLElement("input")}} з атрибутом **`type="date"`** ("тип=дата") створюють поля введення, що дають користувачеві можливість ввести дату: або за допомогою текстового поля, котре перевіряє відповідність введених даних, або особливого інтерфейсу вибору дати. + +Значення результату включає рік, місяць та день, але _не_ час. Типи поля введення {{HTMLElement("input/time", "time")}} підтримує введення часу, а {{HTMLElement("input/datetime-local", "datetime-local")}} – дати разом з часом. + +{{EmbedInteractiveExample("pages/tabbed/input-date.html", "tabbed-shorter")}} + +Користувацький інтерфейс введення в цілому відрізняється між браузерами; зверніться до [Сумісності з браузерами](#sumisnist-iz-brauzeramy) по детальнішу інформацію. В непідтримуваних браузерах контрольний елемент зводиться до [``](/uk/docs/Web/HTML/Element/input/text). + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Значення + Рядок, що представляє дату в форматі YYYY-MM-DD, + або є пустим +
Події + {{domxref("HTMLElement/change_event", "change")}} та + {{domxref("HTMLElement/input_event", "input")}} +
Підтримувані загальні атрибути + {{htmlattrxref("autocomplete", "input")}}, + {{htmlattrxref("list", "input")}}, + {{htmlattrxref("readonly", "input")}}, and + {{htmlattrxref("step", "input")}} +
Атрибути IDL + list, value, valueAsDate, + valueAsNumber. +
Інтерфейс DOM

{{domxref("HTMLInputElement")}}

Методи + {{domxref("HTMLInputElement.select", "select()")}}, + {{domxref("HTMLInputElement.stepDown", "stepDown()")}}, + {{domxref("HTMLInputElement.stepUp", "stepUp()")}} +
+ +## Значення + +Рядок, що представляє дату, введену в поле. Має формат згідно з ISO8601, він описаний у {{SectionOnPage("/uk/docs/Web/HTML/Date_and_time_formats", "Форматі дійсного рядка дати")}}. + +Можна встановити усталене значення поля введення з датою всередині атрибута {{htmlattrxref("value", "input")}}, ось так: + +```html + +``` + +{{EmbedLiveSample('znachennia', 600, 40)}} + +> **Примітка:** Показаний формат дати відрізнятиметься від реального `value`: показана дата форматується _на основі локалі браузера користувача_, однак розібране `value` завжди форматується відповідно до `yyyy-mm-dd`. + +Можна отримати та встановити значення дати за допомогою JavaScript, використовуючи властивості {{domxref("HTMLInputElement")}} `value` та `valueAsNumber`. Наприклад: + +```js +var dateControl = document.querySelector('input[type="date"]'); +dateControl.value = '2017-06-01'; +console.log(dateControl.value); // виводить "2017-06-01" +console.log(dateControl.valueAsNumber); // виводить 1496275200000, мітку часу JavaScript (у мілісекундах) +``` + +Цей код знаходить перший елемент {{HTMLElement("input")}}, чий атрибут `type` має значення `date`, і встановлює його значенням `2017-06-01` (1 червня 2017 року). Потім він зчитує це значення назад у вигляді рядка та числа. + +## Додаткові атрибути + +Поруч з атрибутами, спільними для всіх елементів {{HTMLElement("input")}}, поля `date` мають наступні атрибути. + +### max + +Найпізніша прийнятна дата. Якщо {{htmlattrxref("value", "input")}}, введене в елемент, пізніше, то елемент провалює [валідацію обмежень](/uk/docs/Web/Guide/HTML/Constraint_validation). Якщо значення атрибута `max` не є можливим рядком дати у форматі `yyyy-mm-dd`, то елемент не має максимального значення дати. + +Якщо встановлені й `max`, і `min`, то значення `max` мусить бути рядком дати, що є **пізнішою чи рівною** тій, що в атрибуті `min`. + +### min + +Найраніша прийнятна дата. Якщо {{htmlattrxref("value", "input")}}, введене в елемент, раніше, то елемент провалює [валідацію обмежень](/uk/docs/Web/Guide/HTML/Constraint_validation). Якщо значення атрибута `min` не є можливим рядком дати у форматі `yyyy-mm-dd`, то елемент не має мінімального значення дати. + +Якщо встановлені й `max`, і `min`, то значення `min` мусить бути рядком дати, що є **ранішою чи рівною** тій, що в атрибуті `max`. + +### step + +Атрибут `step` (крок) – число, що вказує відстань між поділками, до котрих має приставати значення, або особливе значення `any`, описане нижче. Лише значення, рівні базі крокування ([`min`](#min), якщо вказаний, інакше – {{htmlattrxref("value", "input")}}, або ж відповідне усталене значення, якщо і цього немає), є дійсними. + +Рядкове значення `any` означає, що крокування не застосовується, тож дозволено будь-яке значення (враховуючи інші обмеження, наприклад, [`min`](#min) і [`max`](#max)). + +> **Примітка:** Коли дані, введені користувачем, не відповідають налаштуванням крокування, {{Glossary("user agent", "користувацький агент")}} може заокруглити до найближчого дійсного значення, віддаючи перевагу числам у напрямку збільшення, коли є два рівновіддалені варіанти. + +Для полів `date` значення `step` задається в днях, а працює – як число мілісекунд, рівне 86.400.000 разів по значення `step` (воно зберігається й працює в мілісекундах). Усталене значення `step` – 1, тобто 1 день. + +> **Примітка:** Якщо вказати `any` як значення `step`, то для полів `date` це матиме такий само ефект, як `1`. + +## Використання полів дати + +Поля введення дати надають зручний інтерфейс вибору дат, а також нормалізують формат дати перед надсиланням на сервер, незалежно від локалі користувача. + +В цьому розділі розглядатиметься просте та складніше використання ``. + +### Базове використання полів дати + +Найпростіше використання `` залучає один `` разом із його {{htmlelement("label")}}, дивіться нижче: + +```html +
+ + +

+
+``` + +{{EmbedLiveSample('bazove-vykorystannia-poliv-daty', 600, 40)}} + +Цей HTML надсилає введену дату за ключем `bday` на `https://example.com` — в результаті URL стане виду `https://example.com/?bday=1955-06-08`. + +### Встановлення максимальної та мінімальної дат + +Можна використовувати атрибути {{htmlattrxref("min", "input")}} і {{htmlattrxref("max", "input")}}, щоб обмежити дати, що можуть бути обрані користувачем. В наступному прикладі встановлена мінімальна дата `2017-04-01` та максимальна `2017-04-30`: + +```html +
+ +
+``` + +{{EmbedLiveSample('vstanovlennia-maksymalnoi-ta-minimalnoi-dat', 600, 40)}} + +Наслідком є те, що можна обрати дні лише у квітні 2017 року: місяць та рік в текстовому полі не редагуються, і дати поза квітнем 2017 не можуть бути обрані у віджеті вибору. + +> **Примітка:** Ви _повинні_ мати змогу використовувати атрибут {{htmlattrxref("step", "input")}}, щоб варіювати число днів, на котрі відбувається стрибок при інкременті (наприклад, щоб можна було вибрати лише суботи). Втім, схоже, що на час написання цього тексту це не у всіх реалізаціях так. + +### Контроль розміру поля введення + +`` не підтримує атрибути розміру форми, наприклад, {{htmlattrxref("size", "input")}}. Віддавайте перевагу [CSS](/uk/docs/Web/CSS) для задання їм розмірів. + +## Валідація + +Усталено `` не перевіряє дійсність введеного значення, окрім його формату. Інтерфейси в загальному не дають ввести будь-що, що не є датою – що корисно – але можна залишити поле пустим чи, в тих браузерах, де поле введення виводиться як запасний варіант `text`, ввести недійсну дату (штибу 32 квітня). + +При використанні для обмеження доступних дат {{htmlattrxref("min", "input")}} і {{htmlattrxref("max", "input")}} (дивіться [Встановлення максимальної та мінімальної дат](#vstanovlennia-maksymalnoii-ta-minimalnoii-dat)) браузери, що це підтримують, покажуть помилку при спробі подати дату, що знаходиться поза межами. Втім, слід повторно перевірити подані результати, щоб пересвідчитися, що значення лежить в заданих межах, – на випадок, якщо вибір дати не повністю підтримується на пристрої користувача. + +Також можна використати атрибут {{htmlattrxref("required", "input")}}, щоб зробити введення дати обов‘язковим: буде показана помилка, якщо спробувати подати пусте поле дати. Це повинно спрацювати в більшості браузерів, навіть якщо вони показують поле дати як текстове. + +Погляньмо на приклад мінімальної та максимальної дат, де поле також є обов‘язковим: + +```html +
+ + +

+ +

+
+``` + +При спробі подати форму з неповною датою (чи датою поза встановленими межами) браузер покаже помилку. Спробуйте пограти з прикладом нижче: + +{{EmbedLiveSample('validatsiia', 600, 100)}} + +Нижче – CSS, використаний у прикладі вище. Використовуються [псевдоелементи](/uk/docs/Web/CSS/Pseudo-elements) {{cssxref(":valid")}} та {{cssxref(":invalid")}}, щоб додати іконку після поля, відповідну дійсності чи недійсності поточного значення. Доводиться встановлювати іконку на {{htmlelement("span")}} після поля, а не саме поле, бо принаймні в Chrome згенерований вміст поля показується всередині контрольного елемента, його не можна ефективно оформити чи щось додати. + +```css +label { + display: flex; + align-items: center; +} + +span::after { + padding-left: 5px; +} + +input:invalid + span::after { + content: '✖'; +} + +input:valid + span::after { + content: '✓'; +} +``` + +> **Застереження:** Валідація на боці клієнта _не усуває потреби_ виконувати валідацію на сервері. Будь-кому легко змінити HTML – чи обійти HTML взагалі, надсилаючи дані напряму на ваш сервер. Якщо ваш сервер не зможе валідувати отримані дані, може статися лихо: дані можуть мати поганий формат, бути занадто великими, бути не того типу тощо. + +## Поводження з підтримкою браузерами + +Браузери, що не підтримують такий тип поля, ввічливо відступають до текстового поля, але це створює проблему сталості користувацького інтерфейсу (представлені контрольні елементи відрізняються) та обробки даних. + +Друга проблема – більш серйозна; при підтримці поля дати значення нормалізується до формату `yyyy-mm-dd`. Однак із текстовим полем браузер не має уявлення, в якому форматі дата повинна бути, і є чимало різних форматів, у котрих люди записують дати. Наприклад: + +- `ddmmyyyy` +- `dd/mm/yyyy` +- `mm/dd/yyyy` +- `dd-mm-yyyy` +- `mm-dd-yyyy` +- `Month dd, yyyy` + +Одним способом це обійти є атрибут {{htmlattrxref("pattern", "input")}} на полі дати. Навіть попри те, що віджет вибору дати його не використовуватиме, запасному текстовому полю такий атрибут знадобиться. Наприклад, спробуйте поглянути на наступне в браузері, що не підтримує поле дати: + +```html +
+ +

+ +

+
+``` + +{{EmbedLiveSample('povodzhennia-z-pidtrymkoiu-brauzeramy', 600, 100)}} + +Якщо подати форму, то буде видно, що браузер показує помилку та підсвічує поле як недійсне, якщо введене не відповідає патернові `####-##-##` (де `#` – цифра від 0 до 9). Звісно, це не зупинить людей від введення недійсних дат чи некоректних форматів. Тож проблема досі є. + +```css hidden +span { + position: relative; +} + +span::after { + right: -18px; + position: absolute; +} + +input:invalid + span::after { + content: '✖'; +} + +input:valid + span::after { + content: '✓'; +} +``` + +Найкращий наразі спосіб роботи з даними у кросбраузерний спосіб – це або мати день, місяць та рік в окремих полях, або використовувати JavaScript-бібліотеку типу [jQuery date picker](https://jqueryui.com/datepicker/). + +## Приклади + +В цьому прикладі створюються два набори елементів користувацького інтерфейсу для вибору дат: нативний `` та набір з трьох елементів {{htmlelement("select")}} – для старших браузерів, що не підтримують нативне поле дати. + +{{EmbedLiveSample('pryklady', 600, 100)}} + +### HTML + +HTML має такий вигляд: + +```html +
+
+ + + +
+

Введіть дату свого народження:

+
+ + + + + + + + + + + + +
+
+``` + +Місяці – намертво вписані в код (вони завжди ті самі), а значення дня й року – динамічно генеруються залежно від обраних місяця й року, а також поточного року (дивіться коментарі коду нижче з детальними поясненнями, як ці функції працюють). + +```css hidden +span { + padding-left: 5px; +} + +input:invalid + span::after { + content: '✖'; +} + +input:valid + span::after { + content: '✓'; +} +``` + +### JavaScript + +Інша частина коду, що може бути цікавою – визначення доступності функціоналу: чи підтримує браузер ``. + +Створюється новий елемент {{htmlelement("input")}} element, потім його `type` встановлюється в `date`, потім негайно відбувається перевірка типу: браузери, що підтримують `date`, повернуть `text`, бо для типу `date` запасним варіантом є тип `text`. Якщо `` не підтримується, то нативний віджет вибору ховається, а натомість показується запасний варіант – ({{htmlelement("select")}}). + +```js +// визначити змінні +var nativePicker = document.querySelector('.nativeDatePicker'); +var fallbackPicker = document.querySelector('.fallbackDatePicker'); +var fallbackLabel = document.querySelector('.fallbackLabel'); + +var yearSelect = document.querySelector('#year'); +var monthSelect = document.querySelector('#month'); +var daySelect = document.querySelector('#day'); + +// спершу приховати запасний варіант +fallbackPicker.style.display = 'none'; +fallbackLabel.style.display = 'none'; + +// перевірити, чи відступає поле дати до запасного текстового варіанту, чи ні +var test = document.createElement('input'); + +try { + test.type = 'date'; +} catch (e) { + console.log(e.message); +} + +// якщо відступає, то виконати код всередині блока if() {} +if (test.type === 'text') { + // приховати нативний віджет вибору та показати запасний варіант + nativePicker.style.display = 'none'; + fallbackPicker.style.display = 'block'; + fallbackLabel.style.display = 'block'; + + // динамічно заповнити дні та роки + // (місяці завжди одні, тому – вписані в код) + populateDays(monthSelect.value); + populateYears(); +} + +function populateDays(month) { + // видалити поточний набір елементів