Date Picker Input
Text input with calendar dropdown for single date or date range selection
Custom Date Format
Add data-format to the container to override the default DD/MM/YYYY. Tokens: YYYY, YY, MM, M, DD, D. Any other character passes through literally. Applies to both Gregorian and Hijri, and both endpoints of a range. Token presence also drives the picker UI — omit the day tokens (MM/YYYY) for a month-only picker, use only year tokens (YYYY) for a year-only picker.
Date Bounds (Min / Max)
Add data-min-date and/or data-max-date to the input — values parsed with the picker's own data-format. Out-of-range day cells, month cells, and years render disabled; prev/next arrows and the Today button also disable at the boundary. Coexists with data-year-before / data-year-after — the tighter side wins. Hand-typed values are validated too: a badly formatted, out-of-range, or reversed-range value shows a localized field error on commit and blocks form submit through the standard forms validation (setCustomValidity), so the bounds can't be bypassed by editing the input directly.
Built-in Features
What you get out of the box with zero configuration
Loaded from nds-extras.min.js and registered as NDS.DatePicker by the loader. Scans for .nds-date-input inside .nds-form-control. Calendar dropdown is created lazily on first click. For dynamic content, call NDS.DatePicker.reinit().
Supports both Gregorian and Hijri (Islamic lunar) calendars. Add the nds-hijri class to the container to switch. Conversion uses an accurate API reference with browser Intl and mathematical fallbacks.
Add the dateRange class to enable start/end date selection. Visual indicators highlight the range with connected cells between start and end dates.
Control the year dropdown range with data-year-before and data-year-after attributes on the input. Defaults work for most use cases.
Month names, weekday labels, and button text render in Arabic or English based on the page language. Add data-lang="ar" on the input to override. Supports RTL and LTR layouts with correct dropdown positioning.
Calendar dropdown automatically flips above the input when there is not enough space below. On mobile, the dropdown centers horizontally for better visibility.
Usage Guidelines
When and how to use the date picker effectively
When to Use
- Date selection in forms where the user needs a calendar view to pick a date
- Booking, scheduling, and event planning interfaces
- Use date range mode for report filters, travel dates, or any start/end date pair
- Use Hijri mode for government forms and services that require Islamic calendar dates
- For simple known dates (birth date, ID expiry), a plain text input with a date mask may be simpler
- Pre-populate the input with a value in DD/MM/YYYY format to set an initial date
Best Practices
- Always pair the date input with a visible label using
<label for>so the field is accessible - Set
data-year-beforeanddata-year-afterto meaningful ranges for the context (a birth date picker needs a wide past range, a booking picker needs a wider future range) - Use
data-year-after="0"on input fields where future dates are not allowed: the year dropdown will stop at the current year - Listen on the
changeevent of the input to react to selection and clear actions, both fire a native bubbling change event - For server-rendered forms that may be re-inserted into the DOM after a route change, call
NDS.DatePicker.reinit()to wire new inputs - To remove a calendar from a specific input (for example in a dynamic list row), call
instance.destroy()on the value returned byNDS.DatePicker.create() - Do not nest a date picker inside another dropmenu or portal: the calendar dropdown uses the dropmenu positioning system and expects to anchor to its own
.nds-form-controlparent
Keyboard Navigation
The calendar grid follows the WAI-ARIA Date Picker Dialog pattern with roving tabindex. Tab moves into the grid and lands on the selected day, today, or the first day of the month.
| Key | Action |
|---|---|
Arrow keys | Move focus one day at a time within the calendar grid. Wraps to the adjacent month when crossing a boundary |
Home | Move focus to the first day of the current week (Sunday) |
End | Move focus to the last day of the current week (Saturday) |
PageUp | Navigate to the previous month and focus the first day of that month |
PageDown | Navigate to the next month and focus the first day of that month |
Shift + PageUp | Navigate back one year (12 months) and focus the first day |
Shift + PageDown | Navigate forward one year (12 months) and focus the first day |
Enter / Space | Select the focused day |
Escape | Close the calendar dropdown (handled by the dropmenu system) |
Data Attributes
| Attribute | Element | Description |
|---|---|---|
data-year-before | .nds-date-input | Number of years before today to include in the year dropdown. Default: 5 |
data-year-after | .nds-date-input | Number of years after today to include in the year dropdown. Default: 0 — omitted (or set to 0), the year list caps at the current year, preventing future year selection |
data-lang | .nds-date-input | Override the calendar language. Values: ar, en. Defaults to the <html lang> attribute |
data-format | .nds-form-container.nds-date-picker | Custom date format. Tokens: YYYY, YY, MM, M, DD, D. Any other character passes through literally. Default: DD/MM/YYYY. Applies to both Gregorian and Hijri; both endpoints of a range use the same format. Token presence also selects the picker UI — omit day tokens for a month picker (day defaults to 1), use only year tokens for a year picker (day+month default to 1) |
data-min-date | .nds-date-input | Earliest selectable date. Parsed with the picker's data-format. Coexists with data-year-before — the tighter side wins. Typed values before it fail form validation |
data-max-date | .nds-date-input | Latest selectable date. Parsed with the picker's data-format. Coexists with data-year-after — the tighter side wins. Typed values after it fail form validation |
data-clearable | .nds-form-container.nds-date-picker | Shows a Clear button in the footer that wipes the input value + state and closes the picker. Auto-enabled in range mode. Boolean (presence-only) |
Events
| Event | Target | When |
|---|---|---|
change | .nds-date-input | Fires on every day selection (bubbling, native). Also fires when the user clicks Clear, setting the input value to an empty string |
CSS Custom Properties
Set on .nds-date-picker-dropdown to control the calendar panel dimensions.
| Property | Default | Description |
|---|---|---|
--dropmenu-width | 100% | Calendar panel width relative to the form control |
--dropmenu-min-width | 350px | Minimum width of the calendar panel |
--dropmenu-max-width | 500px | Maximum width of the calendar panel |
--menu-padding | 0 | Padding override for the dropmenu container. Internal calendar sections supply their own padding |
--btn-size | 40px (32px mobile) | Size of each day cell button in the calendar grid |
JavaScript API
Exposed as window.NDS.DatePicker by nds-extras.min.js. Use NDS.DatePicker.create() to attach a calendar instance to an existing input, and call instance.destroy() to tear it down cleanly.