Interactive demos of hcg-date-picker, a lightweight zero-dependency
JavaScript date picker with calendar popup, datetime, time-only, month-only, year-only,
date range, multiple dates, and calendar event labels.
Try single date selection, enableTime, mode: 'time',
mode: 'month', mode: 'year',
mode: 'range' (with hover preview), mode: 'multiple',
events labels, minDate / maxDate,
disabledDates, enabledDates, firstDayOfWeek,
Arabic locale, button triggers, inline calendar,
theme: 'dark', and the instance API.
Version .
hcg-date-picker - full documentation
Click the input to open a calendar. Click the month/year title to jump to month or year view (useful for birth dates). Use arrow keys to move the focus ring, Enter to select.
<input type="text" id="dp-basic" placeholder="Select a date" readonly>
const picker = hcgDatePicker('#dp-basic');
Attach the picker to a <button>. Click opens the calendar, arrow keys move the focus ring, and onChange updates a preview (the button label stays as-is).
<button type="button" id="date-button">Pick a date</button>
<p id="date-button-preview">Selected: (none)</p>
const preview = document.getElementById('date-button-preview');
const picker = hcgDatePicker('#date-button', {
onChange: (dates, formatted) => {
preview.textContent = 'Selected: ' + (formatted || '(none)');
},
});
Enable time controls under the calendar with enableTime: true.
<input type="text" id="dp-datetime" placeholder="Select date and time" readonly>
const picker = hcgDatePicker('#dp-datetime', {
enableTime: true,
});
Use mode: 'time' for a compact hour and minute picker.
<input type="text" id="dp-time" placeholder="Select a time" readonly>
const picker = hcgDatePicker('#dp-time', {
mode: 'time',
hour12: true,
});
Use mode: 'month' to pick a month and year (no day grid). Default format is Y-m (e.g. 2026-07).
<input type="text" id="dp-month" placeholder="Select a month" readonly>
const picker = hcgDatePicker('#dp-month', {
mode: 'month',
});
Use mode: 'year' to pick a year from a 12-year grid. Default format is Y (e.g. 2026).
<input type="text" id="dp-year" placeholder="Select a year" readonly>
const picker = hcgDatePicker('#dp-year', {
mode: 'year',
});
Pick a start and end date across two months side by side. After the start date, hover days to preview the in-range band before choosing the end.
<input type="text" id="dp-range" placeholder="Start to end" readonly>
const picker = hcgDatePicker('#dp-range', {
mode: 'range',
});
Toggle several dates with mode: 'multiple'. Click a selected day again to remove it. Values are joined with a comma separator.
<input type="text" id="dp-multiple" placeholder="Select multiple dates" readonly>
const picker = hcgDatePicker('#dp-multiple', {
mode: 'multiple',
});
Pass an events map (Y-m-d keys) to show labels under day numbers, like ticket prices on a booking calendar.
<input type="text" id="dp-events" placeholder="Select a date" readonly>
const today = new Date();
const y = today.getFullYear();
const m = String(today.getMonth() + 1).padStart(2, '0');
const d = (day) => String(day).padStart(2, '0');
const picker = hcgDatePicker('#dp-events', {
events: {
[y + '-' + m + '-' + d(5)]: '$189',
[y + '-' + m + '-' + d(12)]: '$249',
[y + '-' + m + '-' + d(18)]: '$159',
[y + '-' + m + '-' + d(22)]: 'Sold out',
},
});
Limit days with minDate / maxDate, blacklist with disabledDates, or whitelist with enabledDates (only listed days selectable).
<input type="text" id="dp-minmax" placeholder="Within allowed range" readonly>
<input type="text" id="dp-enabled" placeholder="Whitelist days only" readonly>
const today = new Date();
const y = today.getFullYear();
const m = today.getMonth();
const minDate = new Date(y, m, 1);
const maxDate = new Date(y, m + 1, 0);
hcgDatePicker('#dp-minmax', {
minDate: minDate,
maxDate: maxDate,
disabledDates: [
new Date(y, m, 15),
],
});
const mondayDates = [];
for (let day = 1; day <= maxDate.getDate(); day += 1) {
const candidate = new Date(y, m, day);
if (candidate.getDay() === 1) mondayDates.push(candidate);
}
hcgDatePicker('#dp-enabled', {
minDate: minDate,
maxDate: maxDate,
firstDayOfWeek: 1,
enabledDates: mondayDates,
});
Set firstDayOfWeek so each calendar row starts on Monday (1) instead of Sunday (0). Values are 0 (Sunday) through 6 (Saturday).
<input type="text" id="dp-first-day" placeholder="Select a date" readonly>
const picker = hcgDatePicker('#dp-first-day', {
firstDayOfWeek: 1,
});
Override weekday names, month names, Today, Clear, and separators with a locale object. This sample uses Arabic labels and dir="rtl" on a range picker.
<input type="text" id="dp-locale" placeholder="البداية إلى النهاية" dir="rtl" readonly>
const picker = hcgDatePicker('#dp-locale', {
mode: 'range',
locale: {
today: 'اليوم',
clear: 'مسح',
rangeSeparator: ' إلى ',
weekdays: ['أحد', 'إثن', 'ثلا', 'أرب', 'خمي', 'جمع', 'سبت'],
months: [
'يناير', 'فبراير', 'مارس', 'أبريل', 'مايو', 'يونيو',
'يوليو', 'أغسطس', 'سبتمبر', 'أكتوبر', 'نوفمبر', 'ديسمبر',
],
},
});
Keep the calendar visible under the input with inline: true.
<input type="text" id="dp-inline" placeholder="Selected date" readonly>
const picker = hcgDatePicker('#dp-inline', {
inline: true,
});
Set theme: 'dark' for the built-in dark palette, or override --hcg-dp-* CSS variables for a custom look. Switch at runtime with setOption('theme', 'light').
<input type="text" id="dp-dark" placeholder="Selected date" readonly>
const picker = hcgDatePicker('#dp-dark', {
theme: 'dark',
inline: true,
});
Open, clear, set a date, and read the formatted value with getFormattedDate().
<input type="text" id="dp-api" placeholder="Use the buttons below" readonly>
<button type="button" id="api-open">Open</button>
<button type="button" id="api-close">Close</button>
<button type="button" id="api-today">Set today</button>
<button type="button" id="api-clear">Clear</button>
<button type="button" id="api-read">Read value</button>
<div id="api-status">Value: (none)</div>
const picker = hcgDatePicker('#dp-api', {
onChange: (dates, formatted) => {
document.getElementById('api-status').textContent =
'Value: ' + (formatted || '(none)');
},
});
document.getElementById('api-open').onclick = () => picker.open();
document.getElementById('api-close').onclick = () => picker.close();
document.getElementById('api-today').onclick = () => picker.setDate(new Date());
document.getElementById('api-clear').onclick = () => picker.clear();
document.getElementById('api-read').onclick = () => {
const formatted = picker.getFormattedDate();
document.getElementById('api-status').textContent =
'Value: ' + (formatted || '(none)');
};