Переклад не закінчено. Будь ласка, допоможіть перекласти цю статтю з англійської.

<input> елементи типу date створюють поле вводу дати з вбудованим інтерфейсом вибору. Результатом вибору будуть рік, місяць та день, без часу. time та datetime-local поля підтримують вибір часу та дати і часу.

UI віджет змінюється від оглядача к оглядачу; для перегляду сумісності дивіться Browser compatibility. Якщо оглядач не підтримує такий віджет, він буде відображений просто як <input type="text">.

Серед оглядачів які підтримуюсь кастомний інтерфейс вибору дати є Chrome/Opera, який виглядає наступним чином:

Edge вибор дати виглядає так:

У Firefox вибір дати буде таким:

Datepicker UI in firefox

Value DOMString представляє дату у YYYY-MM-DD форматі, або пустим
Події change та input
Підримка атрибутів autocomplete, list, readonly, та step
IDL атрибути list, value, valueAsDate, valueAsNumber.
Методи select(), stepDown(), stepUp()

Значення

DOMString представляє значення дати введенної у input. Формат дати описаний у Format of a valid date string in Date and time formats used in HTML.

Ви можете встановити значення за замовчуванням встановивши дату в атрибут value , наприклад:

<input id="date" type="date" value="2017-06-01">

Треба пам'ятати що відображений формат відрізняється від актуального value — відображення формату дати буде вибрано на основі вибраної локалі користувальницького оглядача, тоді як value дати завжди є у форматі yyyy-mm-dd.

Ви також можете взяти чи встановити значення дати у JavaScript використовуючи властивість елементу value , наприклад:

var dateControl = document.querySelector('input[type="date"]');
dateControl.value = '2017-06-01';

Цей код знаходить перший <input> елемент type якого є date і встановлює його значення 2017-06-01 (June 1, 2017).

Додаткові атрибути

Додатково з загальними атрибутами <input> "date" надає наступні додаткові атрибути:

Атрибут Опис
max Максимальна дата яка може бути введена
min Мінімальна дата
readonly Чи є у інпута контент чи нема, він лише для считування
step Інтервал 

max

Остання дата. Якщо встановлена дата value більше ніж ця дата, елемент не пройде constraint validation. Якщо значення max не валідна строка формату yyyy-MM-dd, тоді елемент не буде мати максимальне обмеження.

Це значення має вказувати дату пізнішу або поточну вказанному атрибуту min.

min

Мінімальна дата; дати раніші за вказану не пройдуть constraint validation. Якщо значення  min атрибуту має неавлідний формат yyyy-MM-dd, тоді елемент не матиме мінімального обмеження.

Це значення вказує меньшу або еквівалентну значенню атрибута max.

readonly

A Boolean attribute which, if present, means this field cannot be edited by the user. Its value can, however, still be changed by JavaScript code directly setting the HTMLInputElement.value property.

Note: Because a read-only field cannot have a value, required does not have any effect on inputs with the readonly attribute also specified.

step

The step attribute is a number that specifies the granularity that the value must adhere to, or the special value any, which is described below. Only values which are equal to the basis for stepping (min if specified, value otherwise, and an appropriate default value if neither of those is provided) are valid.

A string value of any means that no stepping is implied, and any value is allowed (barring other constraints, such as min and max).

Note: When the data entered by the user doesn't adhere to the stepping configuration, the user agent may round to the nearest valid value, preferring numbers in the positive direction when there are two equally close options.

Для date інпутів, значення step вказується в днях, скалярні до 86,400,000 (мілісекунди). За замовчуванная step має 1, означаюче 1 день.

Вказання any для step атрибуту робить той самий ефект як і 1.

Використання date інпутів

Поле введення дати зручні на перший погляд — вони надають легкий UI(користувальницький інтерфейс) для вибору дати, і нормалізують формат даних для відправки на сервер, незважаючи на локаль користувача. Однак, існують проблеми підтримки деякими оглядачами <input type="date">.

Подивимось на базові та комлексні використання <input type="date">, щодо сумісності оглядачів ви можете порадитись за посиланням (see Handling browser support). Звичайно, з часом підтримка в оглядачах розповсюдиться. і усі проблеми будуть вирішені.

Базові використання date

Найпростіше використання <input type="date"> передбачає базову <input> і <label> комбінацію елементів, як бачимо нижче:

<form>
  <div>
    <label for="bday">Enter your birthday:</label>
    <input type="date" id="bday" name="bday">
  </div>
</form>

Встановлення мінімальной і максимальної дати

Ви можете використовувати min і max атрибути щоб обмежити дати які будуть вибрані користувачем. В наступному прикладі ми встановлюємо мінімальну дату 2017-04-01 і максимальну дату 2017-04-30:

<form>
  <div>
    <label for="party">Choose your preferred party date:</label>
    <input type="date" id="party" name="party" min="2017-04-01" max="2017-04-30">
  </div>
</form>

Результатом будуть лише дні в Квітні 2017го які можно буде вибрати — тільки "дні", частина текстового значення будуть можливі для зміни, дати поза Квітнем не будуть проскролюватись у віджеті.

Примітка: Ви можете використати step атрибут для того щоб вказати інтервал зміни днів (наприклад ви хотіли б щоб можно були вибрати лише Неділю). Однак, це не завжди ефективно в тих чи іншіх реалізаціях.

Контроль розміру input

<input type="date"> не підтримує розмір форми атрибутами наприклад size. Зверніться до CSS для контролю розміру елементу.

Валідація

За замовчуванням, <input type="date"> не додає жодної валідації на введення значення. UI реалізація загалом не дозволяє уведення будь чого що не є датою — що є добре — але ви всеодно можете лишати поле пустим чи (в оглядачах де інпут відображається простим типом text) ввести неправильну дату (наприклад 32ге Квітня).

Якщо ви використовуєте min і max для обмеження введення дат (дивіться Setting maximum and minimum dates), підтримуючі оглядачі відобразять помилку якщо ви спробуєте відправити дату поза меж вказаних в атрибутах. Однак, перевірте результат щоб запевнитись що значення всередені цих дат, тому що вони можуть не підтримуватись пристрієм користувача.

В додаток, ви можете використовувати required атрибут щоб зробити заповнення дати обьв'язковим — знову ж, буде відображена помилка якщо користувач захоче відправити пусте поле. Принаймні, це буде працювати у більшості оглядачів.

Давайте розглянемо приклад — ми встановили мінімальну і максимальну дату, і також зробили його обов'язковим:

<form>
  <div>
    <label for="party">Choose your preferred party date (required, April 1st to 20th):</label>
    <input type="date" id="party" name="party" min="2017-04-01" max="2017-04-20" required>
    <span class="validity"></span>
  </div>
  <div>
    <input type="submit">
  </div>
</form>

Якщо ви спробуєте відправити форму з незаповненою датою(або з датою поза межами), оглядач відобразить помилку. Спробуйте це самі зробити для перевірки:

Це скріншот приклади оглядача без підтримки віджету дати:

CSS використаний нижче в прикладі. Ми використовуєм правила :valid та :invalid CSS щоб стилізувати відображення валідного чи невалідного введенного значення поля. Ми встановлюємо іконку на <span> біля інпуту, не на самий інпут, тому що у Chrome створений контент розміщений всередені контролю форми, і не може бути застилізований чи відображений коректно.

div {
    margin-bottom: 10px;
    display: flex;
    align-items: center;
}

label {
  display: inline-block;
  width: 300px;
}

input:invalid+span:after {
    content: '✖';
    padding-left: 5px;
}

input:valid+span:after {
    content: '✓';
    padding-left: 5px;
}

Важливо: HTML валідація форми не замінює скрипти які перевіряють чи буле введена інформація у коректному форматі. Це достатньо простий метод щоб додати корекцію до HTML, їх можливо обійти , чи видалити зовсім. Якщо ваша серверна сторона не перевірить відправлені данні, це може бути катастрофа (данні можуть бути дуже великого розміру, або неправильного типу, вам можуть завантажити скрипт взлому і так далі).

Обробка підтримки оглядачів

Як згадано раніше, більша частина проблем з використанням інпуту дати описани  у browser support. Як приклад, дата пікер у Firefox для Android виглядає так:

Непідтримуючи оглядачі точно деградують інпут, це створює проблеми у якості інтерфейсу користувача (представлеий віджет буде іншим), і обробкою даних.

Наступна проблема це більш серьозна; як згадували раніше, за інпутом дати, данні завжди нормалізуються у формат yyyy-mm-dd. З текстовим інпутом оглядач не підтримує формат введених даних, і є багато прикладів як люди вводять дати, наприклад:

  • ddmmyyyy
  • dd/mm/yyyy
  • mm/dd/yyyy
  • dd-mm-yyyy
  • mm-dd-yyyy
  • Month dd yyyy

Єдиний спосіб стосовно цього є лише введення атрибуту pattern. Якщо інпут дати не використовує цей атрибут, то текстовий буде. Наприклад, розгляньте код у непідтримуючих оглядачах:

<form>
  <div>
    <label for="bday">Enter your birthday:</label>
    <input type="date" id="bday" name="bday" required pattern="[0-9]{4}-[0-9]{2}-[0-9]{2}">
    <span class="validity"></span>
  </div>
  <div>
    <input type="submit">
  </div>
</form>

Якщо ви спробуєте відправити це, ви побачете помилку (інпут підсвітеться як невалідний) якщо ви ввели данні які не збігаються з шаблоном nnnn-nn-nn, де n номер від 0 до 9. Звичайно, це не зупинить людей від введення неправильної дати, чи введення у неправильному форматі, як yyyy-dd-mm (де ми очикуємо yyyy-mm-dd). Тож всеж таки маємо проблему.

Найкращий шлях опрацьовувати дати в формах в крос-браузерному форматі на даний момент є введення користувачем дня, місяця, і року в окремих елементах (<select>; (дивіться далі реалізацію), або використовуючи JavaScript бібліотеку jQuery date picker.

Приклади

В цьому прикладі ми створюємо два набори UI елементів для вибору дат: рідний <input type="date"> і набір із трьох <select> елементів для вибору дати в тих оглядачах які не підтримують рідний date інпут.

HTML

HTML виглядає так:

<form>
    <div class="nativeDatePicker">
      <label for="bday">Enter your birthday:</label>
      <input type="date" id="bday" name="bday">
      <span class="validity"></span>
    </div>
    <p class="fallbackLabel">Enter your birthday:</p>
    <div class="fallbackDatePicker">
      <span>
        <label for="day">Day:</label>
        <select id="day" name="day">
        </select>
      </span>
      <span>
        <label for="month">Month:</label>
        <select id="month" name="month">
          <option selected>January</option>
          <option>February</option>
          <option>March</option>
          <option>April</option>
          <option>May</option>
          <option>June</option>
          <option>July</option>
          <option>August</option>
          <option>September</option>
          <option>October</option>
          <option>November</option>
          <option>December</option>
        </select>
      </span>
      <span>
        <label for="year">Year:</label>
        <select id="year" name="year">
        </select>
      </span>
    </div>
</form>

Назви місяців жорстко закодовані (тому що вони завжди однакові), коли дні і роки динамічно згенеровані залежно від того який місяць і рік вибраний, і поточний рік (дивіться коментарі коду нижче для детального пояснення як ці функції працюють).

JavaScript

Друга частина коду розраховує чи підтримує оглядач <input type="date">, ми створюєм <input> елемент, із type date, потім одразу перевіряємо який тип було встановлено — непідтримуючі оглядачі автоматично повернуть тип text, тому що date тип автоматично перетворюється на text. Якщо <input type="date"> не підтримується, ми приховуємо рідний інпут і показуєм UI (<select>) замість нього.

// define variables
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');

// hide fallback initially
fallbackPicker.style.display = 'none';
fallbackLabel.style.display = 'none';

// test whether a new date input falls back to a text input or not
var test = document.createElement('input');
test.type = 'date';

// if it does, run the code inside the if() {} block
if(test.type === 'text') {
  // hide the native picker and show the fallback
  nativePicker.style.display = 'none';
  fallbackPicker.style.display = 'block';
  fallbackLabel.style.display = 'block';

  // populate the days and years dynamically
  // (the months are always the same, therefore hardcoded)
  populateDays(monthSelect.value);
  populateYears();
}

function populateDays(month) {
  // delete the current set of <option> elements out of the
  // day <select>, ready for the next set to be injected
  while(daySelect.firstChild){
    daySelect.removeChild(daySelect.firstChild);
  }

  // Create variable to hold new number of days to inject
  var dayNum;

  // 31 or 30 days?
  if(month === 'January' || month === 'March' || month === 'May' || month === 'July' || month === 'August' || month === 'October' || month === 'December') {
    dayNum = 31;
  } else if(month === 'April' || month === 'June' || month === 'September' || month === 'November') {
    dayNum = 30;
  } else {
  // If month is February, calculate whether it is a leap year or not
    var year = yearSelect.value;
    var isLeap = new Date(year, 1, 29).getMonth() == 1;
    isLeap ? dayNum = 29 : dayNum = 28;
  }

  // inject the right number of new <option> elements into the day <select>
  for(i = 1; i <= dayNum; i++) {
    var option = document.createElement('option');
    option.textContent = i;
    daySelect.appendChild(option);
  }

  // if previous day has already been set, set daySelect's value
  // to that day, to avoid the day jumping back to 1 when you
  // change the year
  if(previousDay) {
    daySelect.value = previousDay;

    // If the previous day was set to a high number, say 31, and then
    // you chose a month with less total days in it (e.g. February),
    // this part of the code ensures that the highest day available
    // is selected, rather than showing a blank daySelect
    if(daySelect.value === "") {
      daySelect.value = previousDay - 1;
    }

    if(daySelect.value === "") {
      daySelect.value = previousDay - 2;
    }

    if(daySelect.value === "") {
      daySelect.value = previousDay - 3;
    }
  }
}

function populateYears() {
  // get this year as a number
  var date = new Date();
  var year = date.getFullYear();

  // Make this year, and the 100 years before it available in the year <select>
  for(var i = 0; i <= 100; i++) {
    var option = document.createElement('option');
    option.textContent = year-i;
    yearSelect.appendChild(option);
  }
}

// when the month or year <select> values are changed, rerun populateDays()
// in case the change affected the number of available days
yearSelect.onchange = function() {
  populateDays(monthSelect.value);
}

monthSelect.onchange = function() {
  populateDays(monthSelect.value);
}

//preserve day selection
var previousDay;

// update what day has been set to previously
// see end of populateDays() for usage
daySelect.onchange = function() {
  previousDay = daySelect.value;
}

Note: Remember that some years have 53 weeks in them (see Weeks per year)! You'll need to take this into consideration when developing production apps.

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

Specification Status Comments
HTML Living Standard
The definition of '<input type="date">' in that specification.
Living Standard
HTML5
The definition of '<input type="date">' in that specification.
Recommendation

Сумісність з оглядачами

Update compatibility data on GitHub
DesktopMobile
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome for AndroidFirefox for AndroidOpera for AndroidSafari on iOSSamsung Internet
type="date"Chrome Full support 20Edge Full support 12Firefox Full support 57IE No support NoOpera Full support 11Safari No support No
Notes
No support No
Notes
Notes The input type is recognized, but there is no date-specific control.
WebView Android Full support YesChrome Android Full support YesFirefox Android Full support 57Opera Android Full support 11Safari iOS Full support 5Samsung Internet Android ?

Legend

Full support  
Full support
No support  
No support
Compatibility unknown  
Compatibility unknown
See implementation notes.
See implementation notes.

Дивіться також

Мітки документа й учасники

Зробили внесок у цю сторінку: cloudgnome
Востаннє оновлена: cloudgnome,