Hello friends,
Tailwind Elements has good Collection of free, popular components like modal, dropdown and many more.
https://tailwind-elements.com/docs/standard/forms/datepicker/
It has a DatePicker made by Tailwindcss and alpine js.
I just rebuild that by angular instead of alpine js
Just Show The code :D
First add TailWindCss to your project:
https://www.npmjs.com/package/@ngneat/tailwind
date-picker.component.ts:
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-DatePicker',
templateUrl: './date-picker.html'
})
export class DatePickerComponent implements OnInit {
MONTH_NAMES = [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December'
];
DAYS = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
showDatepicker = false;
datepickerValue!: string;
month!: number; // !: mean promis it will not be null, and it will definitely be assigned
year!: number;
no_of_days = [] as number[];
blankdays = [] as number[];
constructor() {}
ngOnInit(): void {
this.initDate();
this.getNoOfDays();
}
initDate() {
let today = new Date();
this.month = today.getMonth();
this.year = today.getFullYear();
this.datepickerValue = new Date(this.year, this.month, today.getDate()).toDateString();
}
isToday(date: any) {
const today = new Date();
const d = new Date(this.year, this.month, date);
return today.toDateString() === d.toDateString() ? true : false;
}
getDateValue(date: any) {
let selectedDate = new Date(this.year, this.month, date);
this.datepickerValue = selectedDate.toDateString();
this.showDatepicker = false;
}
getNoOfDays() {
const daysInMonth = new Date(this.year, this.month + 1, 0).getDate();
// find where to start calendar day of week
let dayOfWeek = new Date(this.year, this.month).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.blankdays = blankdaysArray;
this.no_of_days = daysArray;
}
trackByIdentity = (index: number, item: any) => item;
}
date-picker.component.html:
<div class="flex items-center justify-center bg-gray-200 h-full">
<div class="antialiased sans-serif">
<div>
<div class="container mx-auto px-4 py-2 md:py-10">
<div class="mb-5 w-64">
<label for="datepicker" class="font-bold mb-1 text-gray-700 block">Select Date</label>
<div class="relative">
<input type="hidden" name="date" x-ref="date" />
<input
type="text"
readonly
[(ngModel)]="datepickerValue"
(click)="showDatepicker = !showDatepicker"
(keydown.escape)="showDatepicker = false"
class="
w-full
pl-4
pr-10
py-3
leading-none
rounded-lg
shadow-sm
focus:outline-none focus:shadow-outline
text-gray-600
font-medium
"
placeholder="Select date"
/>
<div class="absolute top-0 right-0 px-3 py-2">
<svg class="h-6 w-6 text-gray-400" 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 {{no_of_days.length"></div>
<div {{32 - new Date(year, month, 32).getDate()"></div>
<div {{new Date(year, month).getDay()"></div> -->
<div
class="bg-white mt-12 rounded-lg shadow p-4 absolute top-0 left-0"
style="width: 17rem"
[hidden]="!showDatepicker"
(keydown.away)="showDatepicker = false"
>
<div class="flex justify-between items-center mb-2">
<div>
<span class="text-lg font-bold text-gray-800">{{ MONTH_NAMES[month] }}</span>
<span class="ml-1 text-lg text-gray-600 font-normal">{{ year }}</span>
</div>
<div>
<button
type="button"
class="
transition
ease-in-out
duration-100
inline-flex
cursor-pointer
hover:bg-gray-200
p-1
rounded-full
"
[ngClass]="{ 'cursor-not-allowed opacity-25': month === 0 }"
[disabled]="month === 0 ? true : false"
(click)="month = month - 1"
(click)="getNoOfDays()"
>
<svg
class="h-6 w-6 text-gray-500 inline-flex"
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
type="button"
class="
transition
ease-in-out
duration-100
inline-flex
cursor-pointer
hover:bg-gray-200
p-1
rounded-full
"
[ngClass]="{ 'cursor-not-allowed opacity-25': month === 11 }"
[disabled]="month === 11 ? true : false"
(click)="month = month + 1"
(click)="getNoOfDays()"
>
<svg
class="h-6 w-6 text-gray-500 inline-flex"
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="flex flex-wrap mb-3 -mx-1">
<ng-container *ngFor="let day of DAYS; let index = index">
<div style="width: 14.26%" class="px-1">
<div class="text-gray-800 font-medium text-center text-xs">{{ day }}</div>
</div>
</ng-container>
</div>
<div class="flex flex-wrap -mx-1">
<ng-container *ngFor="let blankday of blankdays">
<div style="width: 14.28%" class="text-center border-none p-1 border-transparent text-sm"></div>
</ng-container>
<ng-container *ngFor="let date of no_of_days; let dateIndex = index; trackBy: trackByIdentity">
<div style="width: 14.28%" class="px-1 mb-1">
<div
(click)="getDateValue(date)"
class="
cursor-pointer
text-center text-sm
rounded-full
leading-loose
transition
ease-in-out
duration-100
"
[ngClass]="{
'bg-blue-500 text-white': isToday(date) === true,
'text-gray-700 hover:bg-blue-200': isToday(date) === false
}"
>
{{ date }}
</div>
</div>
</ng-container>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
Finally Import FormsModule in to the your.module.ts
import { FormsModule } from '@angular/forms';
@NgModule({
imports: [
...,
FormsModule
]
})
That's it, Save and run 😏
Top comments (3)
Great work on this. Not all heroes wear capes. Adding the ability to pick a year to this has proven difficult for me, btw.
It must be easy, maybe just a drop down item
Thanks, it is very useful information.