Skip to content

Datepicker13.10.5

Date and time pickers allow users to select a single or a range of dates and times.


$ npm i @if-design-system/datepicker@13.10.5

Please enter a valid date

Other frameworks visual examples

NOTE! These examples are just a visual reference to how the design can be implemented. They are not a FULLY implemented, but only adjusted to prove the concept of styling datepickers in other frameworks! YMMV.

Edit this section

Usage

Please enter a valid date
Desktop
Mobile
Edit this section

Operational states

January 2020
Mo Tu We Th Fr Sa Su
A date is selected
January 2020
Mo Tu We Th Fr Sa Su
Making a date range selection
January 2020
Mo Tu We Th Fr Sa Su
Period selected
Edit this section

Accessibility

Role, property, state and tabindex attributes

Datepicker dialog

Role Attribute Element Usage
dialog div Identifies the element as a dialog .
aria-modal="true" div Indicates the dialog is modal.
aria-labelledby="IDREF" div Refers to the heading containing the currently displayed month and year, which defines the accessible name for the dialog.
aria-live="polite" div
  • Indicates the element that displays information about keyboard commands for navigating the grid should be automatically announced by screen readers.
  • The script slightly delays display of the information so screen readers are more likely to read it after information related to change of focus.

Calendar navigation buttons

Role Attribute Element Usage
aria-label="String" button Defines the accessible name of the button (e.g. Next Year).
aria-live="polite" button.if.title
  • When the month and/or year changes the content of the button.if.title element is updated.
  • Indicates the button.if.title should be automatically announced by screen readers.

Date grid

Role Attribute Element Usage
grid table
  • Identifies the table element as a grid widget.
  • Since the grid role is applied to a table element, the row, colheader, and gridcell roles do not need to be specified because they are implied by tr, th, and td tags.
aria-labelledby=IDREF table Defines the accessible name for the grid using the button.if.title that shows the month and year of the dates displayed in the grid.
aria-selected="true" td
  • Identifies the cell for the currently selected date, i.e., the date value present in the date input.
  • Only set on the cell representing the currently selected date, no other cells have aria-selected specified.

Keyboard support

Key Function
Esc Closes the datepicker
Space, Enter
  • Select the date, close the dialog, and move focus to the Choose Date button.
  • Update the value of the Date input with the selected date.
  • Update the accessible name of the Choose Date button to include the selected date.
Up Arrow Moves focus to the same day of the previous week.
Down Arrow Moves focus to the same day of the next week.
Right Arrow Moves focus to the next day.
Left Arrow Moves focus to the previous day.
Home Moves focus to the first day (e.g Sunday) of the current week.
End Moves focus to the last day (e.g. Saturday) of the current week.
Page Up
  • Changes the grid of dates to the previous month.
  • Sets focus on the same day of the same week. If that day does not exist, then moves focus to the same day of the previous or next week.
Shift + Page Up
  • Changes the grid of dates to the previous Year.
  • Sets focus on the same day of the same week. If that day does not exist, then moves focus to the same day of the previous or next week.
Page Down
  • Changes the grid of dates to the next month.
  • Sets focus on the same day of the same week. If that day does not exist, then moves focus to the same day of the previous or next week.
Shift + Page Down
  • Changes the grid of dates to the next Year.
  • Sets focus on the same day of the same week. If that day does not exist, then moves focus to the same day of the previous or next week.
Edit this section

Anatomy

January 2020
Mo Tu We Th Fr Sa Su
Choose a date
  1. The datepicker window
  2. Go to previous month
  3. Title, month and year
  4. Go to next month
  5. Name of weekday
  6. Non selectable day
  7. Selected day
  8. Normal selectable day
January 2020
Mo Tu We Th Fr Sa Su
Today markings
  1. Today and active
  2. Today
January 2020
Mo Tu We Th Fr Sa Su
Selecting a date range
  1. Range select start
  2. Range
  3. Range select end
January 2020
Mo Tu We Th Fr Sa Su
Selected a date range
  1. Range select start
  2. Range
  3. Range select end
Edit this section

Specs

January 2020
Mo Tu We Th Fr Sa Su
Datepicker
Edit this section

Options

Class Usage
td.today Marks cell as today
td.is-selecting-start Marks cell as the beginning of the current selection
td.is-selecting Marks cell as a part of a date range currently beeing selected
td.is-selecting-end Marks cell as the end of the currently selecting date range
td.is-selected-start Marks cell as the beginning of the selected date range
td.is-selected Marks cell as currently selected day or part of a selected date range
td.is-selected-end Marks cell as the end of the selected date range
td:focus, td.is-focused Marks the cell as focused
td:hover, td.is-hovered Marks the cell as hovered
td.non-selectable-day Marks cell as a non selectable day. Only used for days before and after current month
Edit this section

Code

Markup

<form action="" autocomplete="off">
  <div class="if input-wrapper">
    <input type="text" class="if input-field date" data-lpignore="true" placeholder="25.6.2021" /><label
      class="if label"
      >Choose a date</label
    >
    <div class="if input-error" id="ids-datepicker-input-error-_o67k6g8uk">Please enter a valid date</div>
    <div class="if backdrop" role="presentation" id="ids-datepicker-backdrop-_o67k6g8uk"></div>
    <div
      class="if datepicker"
      tabindex="0"
      aria-labelledby="label-_o67k6g8uk"
      aria-modal="true"
      role="dialog"
      aria-live="polite"
      id="ids-datepicker-container-_o67k6g8uk"
      aria-hidden="true"
    >
      <button type="button" class="if close"><span class="if axe sr-only">Close</span></button>
      <div class="if header" id="ids-datepicker-header-_o67k6g8uk">
        <button
          id="ids-datepicker-control-prev-year"
          class="if previous year control"
          type="button"
          aria-label="Previous year"
          tabindex="0"
        ></button>
        <button
          id="ids-datepicker-control-prev-month"
          class="if previous month control"
          type="button"
          aria-label="Previous month"
          tabindex="0"
        ></button>
        <button type="button" aria-live="polite" class="if title" id="ids-datepicker-control-title">juni 2021</button>
        <button
          id="ids-datepicker-control-next-month"
          class="if next month control"
          type="button"
          aria-label="Next month"
          tabindex="0"
        ></button>
        <button
          id="ids-datepicker-control-next-year"
          class="if next year control"
          type="button"
          aria-label="Next year"
          tabindex="0"
        ></button>
      </div>
      <table class="if calendar" role="grid" id="ids-datepicker-table-_o67k6g8uk" aria-labelledby="label-_o67k6g8uk">
        <thead class="if">
          <tr class="if">
            <th class="if dayName" scope="col"><abbr title="mandag">man.</abbr></th>
            <th class="if dayName" scope="col"><abbr title="tirsdag">tir.</abbr></th>
            <th class="if dayName" scope="col"><abbr title="onsdag">ons.</abbr></th>
            <th class="if dayName" scope="col"><abbr title="torsdag">tor.</abbr></th>
            <th class="if dayName" scope="col"><abbr title="fredag">fre.</abbr></th>
            <th class="if dayName" scope="col"><abbr title="lørdag">lør.</abbr></th>
            <th class="if dayName" scope="col"><abbr title="søndag">søn.</abbr></th>
          </tr>
        </thead>
        <tbody class="if">
          <tr class="if">
            <td class="if day non-selectable-day" data-day="31"></td>
            <td class="if day" data-day="1" tabindex="-1"></td>
            <td class="if day" data-day="2" tabindex="-1"></td>
            <td class="if day" data-day="3" tabindex="-1"></td>
            <td class="if day" data-day="4" tabindex="-1"></td>
            <td class="if day" data-day="5" tabindex="-1"></td>
            <td class="if day" data-day="6" tabindex="-1"></td>
          </tr>
          <tr class="if">
            <td class="if day" data-day="7" tabindex="-1"></td>
            <td class="if day" data-day="8" tabindex="-1"></td>
            <td class="if day" data-day="9" tabindex="-1"></td>
            <td class="if day" data-day="10" tabindex="-1"></td>
            <td class="if day" data-day="11" tabindex="-1"></td>
            <td class="if day" data-day="12" tabindex="-1"></td>
            <td class="if day" data-day="13" tabindex="-1"></td>
          </tr>
          <tr class="if">
            <td class="if day" data-day="14" tabindex="-1"></td>
            <td class="if day" data-day="15" tabindex="-1"></td>
            <td class="if day" data-day="16" tabindex="-1"></td>
            <td class="if day" data-day="17" tabindex="-1"></td>
            <td class="if day" data-day="18" tabindex="-1"></td>
            <td class="if day" data-day="19" tabindex="-1"></td>
            <td class="if day" data-day="20" tabindex="-1"></td>
          </tr>
          <tr class="if">
            <td class="if day" data-day="21" tabindex="-1"></td>
            <td class="if day" data-day="22" tabindex="-1"></td>
            <td class="if day" data-day="23" tabindex="-1"></td>
            <td class="if day" data-day="24" tabindex="-1"></td>
            <td class="if day today" data-day="25" tabindex="-1"></td>
            <td class="if day" data-day="26" tabindex="-1"></td>
            <td class="if day" data-day="27" tabindex="-1"></td>
          </tr>
          <tr class="if">
            <td class="if day" data-day="28" tabindex="-1"></td>
            <td class="if day" data-day="29" tabindex="-1"></td>
            <td class="if day" data-day="30" tabindex="-1"></td>
            <td class="if day non-selectable-day" data-day="1"></td>
            <td class="if day non-selectable-day" data-day="2"></td>
            <td class="if day non-selectable-day" data-day="3"></td>
            <td class="if day non-selectable-day" data-day="4"></td>
          </tr>
          <tr class="if">
            <td class="if day non-selectable-day is-hidden" data-day="5"></td>
            <td class="if day non-selectable-day is-hidden" data-day="6"></td>
            <td class="if day non-selectable-day is-hidden" data-day="7"></td>
            <td class="if day non-selectable-day is-hidden" data-day="8"></td>
            <td class="if day non-selectable-day is-hidden" data-day="9"></td>
            <td class="if day non-selectable-day is-hidden" data-day="10"></td>
            <td class="if day non-selectable-day is-hidden" data-day="11"></td>
          </tr>
        </tbody>
      </table>
    </div>
  </div>
</form>

JavaScript Library

JavaScript support library for the Datepicker Component.

This component is compatible with CommonJS, ESM (ES6 module) and UMD. See documentation below.

This library has support functions only, and should be used accompanied with a framework or webcomponent.

NOTE! This is not a full implementation to create a vanilla js datepicker, since the usage of datepickers are either from a framework or a webcomponent.

Install

$ npm install @if-design-system/datepicker-js

Or for Yarn:

$ yarn add @if-design-system/datepicker-js

Usage

By script-tag
<script src="datepicker-webcomponent.umd.js"></script>
As an ES6 module
import * as datepicker from '@if-design-system/datepicker-js';

API

datepicker.calendar.isLeapYear(year)

Returns true or false depending if the given year is a leap year or not.

Param Type Description
year Number The year to check
Returns

Boolean

datepicker.calendar.getMonthDays(month, year)

Returns the current number of days for given month in given year.

Param Type Description
month Number The month to get days from
year Number The year to get days from
Returns

Number

datepicker.calendar.generateDayArray(date, dayArray, adjacentMonthDaysArray)

Generates date arrays for the given date object's month.

One array for the current month, and an array for the days in the adjacent months.

Param Type Description
date Date The date objec to use
dayArray Array Current month's days
adjacentMonthDaysArray Array Adjacent month's days
datepicker.calendar.getDayNames(locale = 'en', format = 'short')

Returns the names of a week for the given locale and format. Default value for locale is en, and default format is short.

The locale is always in a IETF BCP 47 language tag format.

Param Type Description Defaults
locale String The locale to use en
format String Current month's days short
Returns

Array, for example:

['man.', 'tir.', 'ons.', 'tor.', 'fre.', 'lør.', 'søn.'];
datepicker.calendar.getMonthNames(locale = 'en', format = 'long')

Returns the names of the months for the given locale and format. Default value for locale is en, and default format is long.

The locale is always in a IETF BCP 47 language tag format.

Param Type Description Defaults
locale String The locale to use en
format String Current month's days long
Returns

Array, for example:

['januar', 'februar', 'mars', 'april', 'mai', 'juni', 'juli', 'august', 'september', 'oktober', 'november', 'desember'];
datepicker.calendar.getDaysOfPreviousMonth(month, year)

Returns the current number of days in the previous month for given month in given year.

Param Type Description
month Number The month to get days from
year Number The year to get days from
Returns

Number

datepicker.calendar.isWeekend(year, month, day)

Returns true or false depending if the given date is a weekend or not.

Param Type Description
year Number The year to check
month Number The month to check
day Number The day to check
Returns

Boolean

datepicker.date.create(str)

Returns a date object if str is a valid date string.

Param Type Description
str String The date string to create a date object from
Returns

Date

Throws

When given str is not a valid date string.

Error('Invalid Date');
datepicker.date.isValid(day, month, year)

Returns true or false depending if the given date is a valid date.

Param Type Description
day Number The day to check
month Number The month to check
year Number The year to check
Returns

Boolean

datepicker.date.getNewDateObject(year, month, day)

Returns a new date object based on the given date.

Param Type Description
year Number The year to check
month Number The month to check
day Number The day to check
Returns

Date

datepicker.formats.list

A JavaScript Object containing the current date formats for our supported locales.

export const list = {
  no: {
    format: 'DD.MM.YYYY',
    example: '10.11.1983',
    regex: '(\\d{1,2})[.](\\d{1,2})[.](\\d{4})'
  },
  sv: {
    format: 'YYYY-MM-DD',
    example: '1983-11-10',
    regex: '(\\d{4})[-](\\d{1,2})[-](\\d{1,2})'
  },
  da: {
    format: 'DD.MM.YYYY',
    example: '10.11.1983',
    regex: '(\\d{1,2})[.](\\d{1,2})[.](\\d{4})'
  },
  fi: {
    format: 'DD.MM.YYYY',
    example: '10.11.1983',
    regex: '(\\d{1,2})[.](\\d{1,2})[.](\\d{4})'
  },
  et: {
    format: 'DD.MM.YYYY',
    example: '10.11.1983',
    regex: '(\\d{1,2})[.](\\d{1,2})[.](\\d{4})'
  },
  lv: {
    format: 'YYYY.MM.DD.',
    example: '1983.11.10.',
    regex: '(\\d{4})[.](\\d{1,2})[.](\\d{1,2})[.]'
  },
  lt: {
    format: 'YYYY-MM-DD',
    example: '1983-11-10',
    regex: '(\\d{4})[-](\\d{1,2})[-](\\d{1,2})'
  },
  ru: {
    format: 'DD.MM.YYYY',
    example: '10.11.1983',
    regex: '(\\d{1,2})[.](\\d{1,2})[.](\\d{4})'
  },
  kl: {
    format: 'YYYY-MM-DD',
    example: '1983-11-10',
    regex: '(\\d{4})[-](\\d{1,2})[-](\\d{1,2})'
  },
  en: {
    format: 'DD/MM/YYYY',
    example: '10/11/1983',
    regex: '(\\d{1,2})[/](\\d{1,2})[/](\\d{4})'
  }
};
datepicker.formats.getFormatByLocale(locale)

Returns the format by given locale. If no match is found, no is used as a locale.

The locale is always in a IETF BCP 47 language tag format.

Param Type Description
locale String The locale to use
Returns

Object, for example:

{
  format: 'DD.MM.YYYY',
  example: '10.11.1983',
  regex: '(\\d{1,2})[.](\\d{1,2})[.](\\d{4})'
}
datepicker.initiator.position(input)

Positions the initiator button for the datepicker correctly over the given input element.

Param Type Description
input <input> The input element used to position the initiator button from
datepicker.initiator.onResize(input)

An resize event handler for the initiator

Param Type Description
input <input> The input element used to position the initiator button from
datepicker.initiator.onDOMContentLoaded(input)

An DOMContentLoaded event handler for the initiator

Param Type Description
input <input> The input element used to position the initiator button from
datepicker.initiator.init(input)

Initiates the event handlers for the initiator of the given input element.

Param Type Description
input <input> The input element used to position the initiator button from

Webcomponent

Install

$ npm install @if-design-system/datepicker-webcomponent

Or for Yarn:

$ yarn add @if-design-system/datepicker-webcomponent

Usage

<div class="if input-wrapper"
  <input id="datepicker-01" name="datepicker-01" type="text" class="if input-field date" />
  <label for="datepicker-01" class="if label">Choose date</label>
  <div class="if input-error">Please enter a valid date</div>
  <ids-datepicker></ids-datepicker>
</div>
<script src="…datepicker-webcomponent.umd.js"></script>
Persist on select

Use data-persist-on-select to not close the datepicker dialog when date is selected

<form class="if" autocomplete="off">
  <div class="if input-wrapper">
    <input type="text" class="if input-field date is-optional" />
    <label class="if input-label">Choose date</label>
    <div class="if input-error">Please enter a valid date</div>
    <ids-datepicker data-persist-on-select> </ids-datepicker>
  </div>
</form>
Please enter a valid date
Ignore on focus

Use data-ignore-on-focus to open the datepicker from an external initiator.

<form class="if" autocomplete="off">
  <div class="if input-wrapper">
    <input type="text" class="if input-field date is-optional" />
    <label class="if input-label">Choose date</label>
    <div class="if input-error">Please enter a valid date</div>
    <ids-datepicker data-ignore-on-focus> </ids-datepicker>
  </div>
</form>
Please enter a valid date
Open on init

Use data-open to open datepicker on init.

<form class="if" autocomplete="off">
  <div class="if input-wrapper">
    <input type="text" class="if input-field date" />
    <label class="if input-label">Choose date</label>
    <div class="if input-error">Please enter a valid date</div>
    <ids-datepicker data-open> </ids-datepicker>
  </div>
</form>
Please enter a valid date
Disable weekend selection

Use data-disable-weekend to disable weekend selection.

<form class="if" autocomplete="off">
  <div class="if input-wrapper">
    <input type="text" class="if input-field date" />
    <label class="if input-label">Choose date</label>
    <div class="if input-error">Please enter a valid date</div>
    <ids-datepicker data-disable-weekend> </ids-datepicker>
  </div>
</form>
Please enter a valid date
Custom locale

Use data-locale to enforce the locale to be used.

<form class="if" autocomplete="off">
  <div class="if input-wrapper">
    <input type="text" class="if input-field date" />
    <label class="if input-label">Choose date</label>
    <div class="if input-error">Please enter a valid date</div>
    <ids-datepicker data-locale="lv"> </ids-datepicker>
  </div>
</form>
Please enter a valid date
Min and max date

Use data-min-date and data-max-date to let the user only select between those dates.

<form class="if" autocomplete="off">
  <div class="if input-wrapper">
    <input type="text" class="if input-field date" />
    <label class="if input-label">Choose date</label>
    <div class="if input-error">Please enter a valid date</div>
    <ids-datepicker data-min-date="11.5.2021" data-max-date="18.6.2021"> </ids-datepicker>
  </div>
</form>
Please enter a valid date
Set init date to a different date

data-init-date can be any valid date string or a date format for the current locale.

<form class="if" autocomplete="off">
  <div class="if input-wrapper">
    <input type="text" class="if input-field date" />
    <label class="if input-label">Choose date</label>
    <div class="if input-error">Please enter a valid date</div>
    <ids-datepicker data-init-date="1995-12-17T03:24:00"> </ids-datepicker>
  </div>
</form>
Please enter a valid date
Set init date to today
<form class="if" autocomplete="off">
  <div class="if input-wrapper">
    <input type="text" class="if input-field date" />
    <label class="if input-label">Choose date</label>
    <div class="if input-error">Please enter a valid date</div>
    <ids-datepicker data-init-date="current"> </ids-datepicker>
  </div>
</form>
Please enter a valid date
Pattern validation
<form class="if" autocomplete="off">
  <div class="if input-wrapper">
    <input type="text" class="if input-field date" />
    <label class="if input-label">Choose date</label>
    <div class="if input-error">Please enter a valid date</div>
    <ids-datepicker data-use-pattern> </ids-datepicker>
  </div>
</form>
Please enter a valid date
Mark special days

You can also send in an object to mark special days, like holidays.

In this example, we are using Norwegian holidays (public/bank).

Given this markup, notice the id-attribute:

<form class="if" autocomplete="off">
<div class="if input-wrapper">
    <input type="text" class="if input-field date is-optional" />
    <label class="if input-label">Choose date</label>
    <div class="if input-error">Please enter a valid date</div>
    <ids-datepicker id="marked-special-day">
  </ids-datepicker>
</form>

And this object in given format:

{"1617400800000": {
    "date": "2021-04-03 00:00:00",
    "name": "Påskeaften",
  },}

And this code:

const _marked_special_day_datepicker_wc = document.getElementById('marked-special-day');
const _special_days = {
  '1609455600000': {
    date: '2021-01-01 00:00:00',
    name: 'Første nyttårsdag'
  },
  '1617228000000': {
    date: '2021-04-01 00:00:00',
    name: 'Skjærtorsdag'
  },
  '1617314400000': {
    date: '2021-04-02 00:00:00',
    name: 'Langfredag'
  },
  '1617400800000': {
    date: '2021-04-03 00:00:00',
    name: 'Påskeaften'
  },
  '1617487200000': {
    date: '2021-04-04 00:00:00',
    name: 'Første påskedag'
  },
  '1617573600000': {
    date: '2021-04-05 00:00:00',
    name: 'Andre påskedag'
  },
  '1619820000000': {
    date: '2021-05-01 00:00:00',
    name: 'Arbeidernes dag'
  },
  '1620856800000': {
    date: '2021-05-13 00:00:00',
    name: 'Kristi himmelfartsdag'
  },
  '1621202400000': {
    date: '2021-05-17 00:00:00',
    name: '17. mai'
  },
  '1621720800000': {
    date: '2021-05-23 00:00:00',
    name: 'Første pinsedag'
  },
  '1621807200000': {
    date: '2021-05-24 00:00:00',
    name: 'Andre pinsedag'
  },
  '1640300400000': {
    date: '2021-12-24 00:00:00',
    name: 'Julaften'
  },
  '1640386800000': {
    date: '2021-12-25 00:00:00',
    name: 'Første Juledag'
  },
  '1640473200000': {
    date: '2021-12-26 00:00:00',
    name: 'Andre juledag'
  },
  '1640955600000': {
    date: '2021-12-31 14:00:00',
    name: 'Nyttårsaften'
  }
};

_marked_special_day_datepicker_wc.specialDays = _special_days;

A datepicker with marked days for the provided days will render.

Properties

Property Type Description
data-min-date String The minimum date used for selection
data-max-date String The maximum date used for selection
data-locale String The locale to be used, default is html[lang] or navigatior.language
data-disable-weekend Boolean Disabled weekend selection
data-init-date String Start with this date
data-use-pattern Boolean Use the pattern-attribute for validation
data-open Boolean Open on init
data-ignore-on-focus Boolean Do not open on focus, but by external initiator
data-persist-on-select Boolean Do not close the datepicker when date is selected
Edit this section

Contact us