Date Picker
A date picker element that can be used to select a date.
+
Tailwind and Alpine
Copied!
<div x-data="{
datePickerOpen: false,
datePickerValue: '',
datePickerFormat: 'M d, Y',
datePickerMonth: '',
datePickerYear: '',
datePickerDay: '',
datePickerDaysInMonth: [],
datePickerBlankDaysInMonth: [],
datePickerMonthNames: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
datePickerDays: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
datePickerDayClicked(day) {
let selectedDate = new Date(this.datePickerYear, this.datePickerMonth, day);
this.datePickerDay = day;
this.datePickerValue = this.datePickerFormatDate(selectedDate);
this.datePickerIsSelectedDate(day);
this.datePickerOpen = false;
},
datePickerPreviousMonth(){
if (this.datePickerMonth == 0) {
this.datePickerYear--;
this.datePickerMonth = 12;
}
this.datePickerMonth--;
this.datePickerCalculateDays();
},
datePickerNextMonth(){
if (this.datePickerMonth == 11) {
this.datePickerMonth = 0;
this.datePickerYear++;
} else {
this.datePickerMonth++;
}
this.datePickerCalculateDays();
},
datePickerIsSelectedDate(day) {
const d = new Date(this.datePickerYear, this.datePickerMonth, day);
return this.datePickerValue === this.datePickerFormatDate(d) ? true : false;
},
datePickerIsToday(day) {
const today = new Date();
const d = new Date(this.datePickerYear, this.datePickerMonth, day);
return today.toDateString() === d.toDateString() ? true : false;
},
datePickerCalculateDays() {
let daysInMonth = new Date(this.datePickerYear, this.datePickerMonth + 1, 0).getDate();
// find where to start calendar day of week
let dayOfWeek = new Date(this.datePickerYear, this.datePickerMonth).getDay();
let blankdaysArray = [];
for (var i = 1; i <= dayOfWeek; i++) {
blankdaysArray.push(i);
}
let daysArray = [];
for (var i = 1; i <= daysInMonth; i++) {
daysArray.push(i);
}
this.datePickerBlankDaysInMonth = blankdaysArray;
this.datePickerDaysInMonth = daysArray;
},
datePickerFormatDate(date) {
let formattedDay = this.datePickerDays[date.getDay()];
let formattedDate = ('0' + date.getDate()).slice(-2); // appends 0 (zero) in single digit date
let formattedMonth = this.datePickerMonthNames[date.getMonth()];
let formattedMonthShortName = this.datePickerMonthNames[date.getMonth()].substring(0, 3);
let formattedMonthInNumber = ('0' + (parseInt(date.getMonth()) + 1)).slice(-2);
let formattedYear = date.getFullYear();
if (this.datePickerFormat === 'M d, Y') {
return `${formattedMonthShortName} ${formattedDate}, ${formattedYear}`;
}
if (this.datePickerFormat === 'MM-DD-YYYY') {
return `${formattedMonthInNumber}-${formattedDate}-${formattedYear}`;
}
if (this.datePickerFormat === 'DD-MM-YYYY') {
return `${formattedDate}-${formattedMonthInNumber}-${formattedYear}`;
}
if (this.datePickerFormat === 'YYYY-MM-DD') {
return `${formattedYear}-${formattedMonthInNumber}-${formattedDate}`;
}
if (this.datePickerFormat === 'D d M, Y') {
return `${formattedDay} ${formattedDate} ${formattedMonthShortName} ${formattedYear}`;
}
return `${formattedMonth} ${formattedDate}, ${formattedYear}`;
},
}" x-init="
currentDate = new Date();
if (datePickerValue) {
currentDate = new Date(Date.parse(datePickerValue));
}
datePickerMonth = currentDate.getMonth();
datePickerYear = currentDate.getFullYear();
datePickerDay = currentDate.getDay();
datePickerValue = datePickerFormatDate( currentDate );
datePickerCalculateDays();
" x-cloak>
<div class="container px-4 py-2 mx-auto md:py-10">
<div class="w-full mb-5">
<label for="datepicker" class="block mb-1 text-sm font-medium text-neutral-500">Select Date</label>
<div class="relative w-[17rem]">
<input x-ref="datePickerInput" type="text" @click="datePickerOpen=!datePickerOpen" x-model="datePickerValue" x-on:keydown.escape="datePickerOpen=false" class="flex w-full h-10 px-3 py-2 text-sm bg-white border rounded-md text-neutral-600 border-neutral-300 ring-offset-background placeholder:text-neutral-400 focus:border-neutral-300 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-neutral-400 disabled:cursor-not-allowed disabled:opacity-50" placeholder="Select date" readonly />
<div @click="datePickerOpen=!datePickerOpen; if(datePickerOpen){ $refs.datePickerInput.focus() }" class="absolute top-0 right-0 px-3 py-2 cursor-pointer text-neutral-400 hover:text-neutral-500">
<svg class="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" /></svg>
</div>
<div
x-show="datePickerOpen"
x-transition
@click.away="datePickerOpen = false"
class="absolute top-0 left-0 max-w-lg p-4 mt-12 antialiased bg-white border rounded-lg shadow w-[17rem] border-neutral-200/70">
<div class="flex items-center justify-between mb-2">
<div>
<span x-text="datePickerMonthNames[datePickerMonth]" class="text-lg font-bold text-gray-800"></span>
<span x-text="datePickerYear" class="ml-1 text-lg font-normal text-gray-600"></span>
</div>
<div>
<button @click="datePickerPreviousMonth()" type="button" class="inline-flex p-1 transition duration-100 ease-in-out rounded-full cursor-pointer focus:outline-none focus:shadow-outline hover:bg-gray-100">
<svg class="inline-flex w-6 h-6 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7" /></svg>
</button>
<button @click="datePickerNextMonth()" type="button" class="inline-flex p-1 transition duration-100 ease-in-out rounded-full cursor-pointer focus:outline-none focus:shadow-outline hover:bg-gray-100">
<svg class="inline-flex w-6 h-6 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" /></svg>
</button>
</div>
</div>
<div class="grid grid-cols-7 mb-3">
<template x-for="(day, index) in datePickerDays" :key="index">
<div class="px-0.5">
<div x-text="day" class="text-xs font-medium text-center text-gray-800"></div>
</div>
</template>
</div>
<div class="grid grid-cols-7">
<template x-for="blankDay in datePickerBlankDaysInMonth">
<div class="p-1 text-sm text-center border border-transparent"></div>
</template>
<template x-for="(day, dayIndex) in datePickerDaysInMonth" :key="dayIndex">
<div class="px-0.5 mb-1 aspect-square">
<div
x-text="day"
@click="datePickerDayClicked(day)"
:class="{
'bg-neutral-200': datePickerIsToday(day) == true,
'text-gray-600 hover:bg-neutral-200': datePickerIsToday(day) == false && datePickerIsSelectedDate(day) == false,
'bg-neutral-800 text-white hover:bg-opacity-75': datePickerIsSelectedDate(day) == true
}"
class="flex items-center justify-center text-sm leading-none text-center rounded-full cursor-pointer h-7 w-7"></div>
</div>
</template>
</div>
</div>
</div>
</div>
</div>
</div>
Data
Below you will find the data properties available in the x-data
attribute of this element.
Property and Description | Description |
---|---|
datePickerOpen | If the date picker is open (true or false) |
If the date picker is open (true or false) | |
datePickerValue | The default date value. If left empty the current date will be used |
The default date value. If left empty the current date will be used | |
datePickerFormat | You can choose a few different formats to display the date. See all available formats in the datePickerFormatDate() method. |
You can choose a few different formats to display the date. See all available formats in the datePickerFormatDate() method. | |
datePickerMonth | Numerical value of the current month (0-11) |
Numerical value of the current month (0-11) | |
datePickerYear | Numerical value of the current year |
Numerical value of the current year | |
datePickerDay | Numerical value of the current day |
Numerical value of the current day | |
datePickerDaysInMonth | Array containing the number of days in the selected month |
Array containing the number of days in the selected month | |
datePickerBlankDaysInMonth | Array containing the number of blank days before the first day of the month |
Array containing the number of blank days before the first day of the month | |
datePickerMonthNames | Array containing the names of the months |
Array containing the names of the months | |
datePickerDays | Array containing the names of the days |
Array containing the names of the days | |
datePickerDayClicked(day) | When a day is clicked on the datepicker set the new date value |
When a day is clicked on the datepicker set the new date value | |
datePickerPreviousMonth() | Go to the previous month |
Go to the previous month | |
datePickerNextMonth() | Go to the next month |
Go to the next month | |
datePickerIsSelectedDate(day) | Check if the day is the selected date |
Check if the day is the selected date | |
datePickerIsToday(day) | Check if the day is today |
Check if the day is today | |
datePickerCalculateDays() | Calculate the number of days in the month |
Calculate the number of days in the month | |
datePickerFormatDate(date) | Format the date to the selected format |
Format the date to the selected format |
More Examples
Below you will find more Date Picker examples you may wish to use in your projects.
Copied!
<div x-data="{
datePickerOpen: false,
datePickerValue: '',
datePickerFormat: 'M d, Y',
datePickerMonth: '',
datePickerYear: '',
datePickerDay: '',
datePickerDaysInMonth: [],
datePickerBlankDaysInMonth: [],
datePickerMonthNames: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
datePickerDays: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
datePickerDayClicked(day) {
let selectedDate = new Date(this.datePickerYear, this.datePickerMonth, day);
this.datePickerDay = day;
this.datePickerValue = this.datePickerFormatDate(selectedDate);
this.datePickerIsSelectedDate(day);
this.datePickerOpen = false;
},
datePickerPreviousMonth(){
if (this.datePickerMonth == 0) {
this.datePickerYear--;
this.datePickerMonth = 12;
}
this.datePickerMonth--;
this.datePickerCalculateDays();
},
datePickerNextMonth(){
if (this.datePickerMonth == 11) {
this.datePickerMonth = 0;
this.datePickerYear++;
} else {
this.datePickerMonth++;
}
this.datePickerCalculateDays();
},
datePickerIsSelectedDate(day) {
const d = new Date(this.datePickerYear, this.datePickerMonth, day);
return this.datePickerValue === this.datePickerFormatDate(d) ? true : false;
},
datePickerIsToday(day) {
const today = new Date();
const d = new Date(this.datePickerYear, this.datePickerMonth, day);
return today.toDateString() === d.toDateString() ? true : false;
},
datePickerCalculateDays() {
let daysInMonth = new Date(this.datePickerYear, this.datePickerMonth + 1, 0).getDate();
// find where to start calendar day of week
let dayOfWeek = new Date(this.datePickerYear, this.datePickerMonth).getDay();
let blankdaysArray = [];
for (var i = 1; i <= dayOfWeek; i++) {
blankdaysArray.push(i);
}
let daysArray = [];
for (var i = 1; i <= daysInMonth; i++) {
daysArray.push(i);
}
this.datePickerBlankDaysInMonth = blankdaysArray;
this.datePickerDaysInMonth = daysArray;
},
datePickerFormatDate(date) {
let formattedDay = this.datePickerDays[date.getDay()];
let formattedDate = ('0' + date.getDate()).slice(-2); // appends 0 (zero) in single digit date
let formattedMonth = this.datePickerMonthNames[date.getMonth()];
let formattedMonthShortName = this.datePickerMonthNames[date.getMonth()].substring(0, 3);
let formattedMonthInNumber = ('0' + (parseInt(date.getMonth()) + 1)).slice(-2);
let formattedYear = date.getFullYear();
if (this.datePickerFormat === 'M d, Y') {
return `${formattedMonthShortName} ${formattedDate}, ${formattedYear}`;
}
if (this.datePickerFormat === 'MM-DD-YYYY') {
return `${formattedMonthInNumber}-${formattedDate}-${formattedYear}`;
}
if (this.datePickerFormat === 'DD-MM-YYYY') {
return `${formattedDate}-${formattedMonthInNumber}-${formattedYear}`;
}
if (this.datePickerFormat === 'YYYY-MM-DD') {
return `${formattedYear}-${formattedMonthInNumber}-${formattedDate}`;
}
if (this.datePickerFormat === 'D d M, Y') {
return `${formattedDay} ${formattedDate} ${formattedMonthShortName} ${formattedYear}`;
}
return `${formattedMonth} ${formattedDate}, ${formattedYear}`;
},
}" x-init="
currentDate = new Date();
if (datePickerValue) {
currentDate = new Date(Date.parse(datePickerValue));
}
datePickerMonth = currentDate.getMonth();
datePickerYear = currentDate.getFullYear();
datePickerDay = currentDate.getDay();
datePickerValue = datePickerFormatDate( currentDate );
datePickerCalculateDays();
" x-cloak>
<div class="container px-4 py-2 mx-auto md:py-10">
<div class="w-64 mb-5">
<label for="datepicker" class="block mb-1 text-sm font-medium text-neutral-500">Select Date</label>
<div class="relative w-[17rem]">
<input x-ref="datePickerInput" type="text" @click="datePickerOpen=!datePickerOpen" x-model="datePickerValue" x-on:keydown.escape="datePickerOpen=false" class="flex w-full h-10 px-3 py-2 text-sm bg-white border-2 text-neutral-600 border-neutral-600 ring-offset-background placeholder:text-neutral-400 focus:border-neutral-800 focus:text-neutral-800 focus:outline-none focus:ring-0 disabled:cursor-not-allowed disabled:opacity-50" placeholder="Select date" readonly />
<div @click="datePickerOpen=!datePickerOpen; if(datePickerOpen){ $refs.datePickerInput.focus() }" :class="{ 'text-neutral-600 hover:text-neutral-800' : !datePickerOpen, 'text-neutral-800' : datePickerOpen }" class="absolute top-0 right-0 px-3 py-2 cursor-pointer">
<svg class="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" /></svg>
</div>
<div
x-show="datePickerOpen"
x-transition
@click.away="datePickerOpen = false"
class="absolute top-0 left-0 max-w-lg p-4 mt-12 antialiased bg-white border-2 border-neutral-800 shadow w-[17rem] border-neutral-200/70">
<div class="flex items-center justify-between mb-2">
<div>
<span x-text="datePickerMonthNames[datePickerMonth]" class="text-lg font-bold text-gray-800"></span>
<span x-text="datePickerYear" class="ml-1 text-lg font-normal text-gray-600"></span>
</div>
<div>
<button @click="datePickerPreviousMonth()" type="button" class="inline-flex p-1 transition duration-100 ease-in-out cursor-pointer focus:outline-none focus:shadow-outline hover:bg-gray-100">
<svg class="inline-flex w-6 h-6 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7" /></svg>
</button>
<button @click="datePickerNextMonth()" type="button" class="inline-flex p-1 transition duration-100 ease-in-out cursor-pointer focus:outline-none focus:shadow-outline hover:bg-gray-100">
<svg class="inline-flex w-6 h-6 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" /></svg>
</button>
</div>
</div>
<div class="grid grid-cols-7 mb-3">
<template x-for="(day, index) in datePickerDays" :key="index">
<div class="px-0.5">
<div x-text="day" class="text-xs font-medium text-center text-gray-800"></div>
</div>
</template>
</div>
<div class="grid grid-cols-7">
<template x-for="blankDay in datePickerBlankDaysInMonth">
<div class="p-1 text-sm text-center border border-transparent"></div>
</template>
<template x-for="(day, dayIndex) in datePickerDaysInMonth" :key="dayIndex">
<div class="px-0.5 mb-1 aspect-square">
<div
x-text="day"
@click="datePickerDayClicked(day)"
:class="{
'bg-neutral-200': datePickerIsToday(day) == true,
'text-gray-600 hover:bg-neutral-200': datePickerIsToday(day) == false && datePickerIsSelectedDate(day) == false,
'bg-neutral-800 text-white hover:bg-opacity-75': datePickerIsSelectedDate(day) == true
}"
class="flex items-center justify-center text-sm leading-none text-center cursor-pointer h-7 w-7"></div>
</div>
</template>
</div>
</div>
</div>
</div>
</div>
</div>