DEV Community

timsar2
timsar2

Posted on • Updated on

Create DatePicker By TailWindCss + Angular

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

Alt Text

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;
}

Enter fullscreen mode Exit fullscreen mode

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>

Enter fullscreen mode Exit fullscreen mode

Finally Import FormsModule in to the your.module.ts

import { FormsModule } from '@angular/forms';
@NgModule({
  imports: [
    ..., 
    FormsModule
  ]
})
Enter fullscreen mode Exit fullscreen mode

That's it, Save and run 😏

Latest comments (3)

Collapse
 
andrejs_sinkevics profile image
Andrejs Sinkevics

Thanks, it is very useful information.

Collapse
 
hiddenkirby profile image
Ryan Kirby

Great work on this. Not all heroes wear capes. Adding the ability to pick a year to this has proven difficult for me, btw.

Collapse
 
timsar2 profile image
timsar2 • Edited

It must be easy, maybe just a drop down item