Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
May 7, 2020 04:49 pm GMT

Angular: How to build a full screen calendar like Outlook

In an Angular project a while back I needed to display a full screen calendar like the one in outlook. So as a good lazy developer I start looking on the web for a nmp package that could do the job.
To my surprise I didn't find anything that could cover my needs 100% so I went on and built one!

This is the end result:

P.S.: Please be kind with me, HTML and CSS are not my strong part.

Here is the coding story of how I did:

1st let's have our Angular component

This is our starting point an Angular component and an Array that will hold the days that our calendar will display

@Component({  selector: 'my-app',  templateUrl: './app.component.html',  styleUrls: [ './app.component.css' ]})export class AppComponent implements OnInit {  public calendar: CalendarDay[] = []; }

2nd let's see how the CalendarDay class looks like

export class CalendarDay {  public date: Date;  public title: string;  public isPastDate: boolean;  public isToday: boolean;  constructor(d: Date) {    this.date = d;    this.isPastDate = d.setHours(0, 0, 0, 0) < new Date().setHours(0, 0, 0, 0);    this.isToday = d.setHours(0, 0, 0, 0) == new Date().setHours(0, 0, 0, 0);  }}

Let explain the constructor a little bit.

  this.isPastDate = d.setHours(0, 0, 0, 0) < new Date().setHours(0, 0, 0, 0);  this.isToday = d.setHours(0, 0, 0, 0) == new Date().setHours(0, 0, 0, 0);

I set property isPastDate so my calendar knows how to display or disable past dates and isToday property so UI knows how to draw the today's date.

The reason I use .setHours(0,0,0,0) is cause I want to be sure I'm comparing the beginning of the day and hours don't matter.

3rd let's populate our calendar with the needed days

I have comments in my code that explain the logic.

  ngOnInit(): void {    // here we initialize the calendar    this.generateCalendarDays();  }  private generateCalendarDays(): void {    // we reset our calendar every time    this.calendar = [];    // we set the date     let day: Date = new Date();    // here we find the first day that our calendar will start from    // it would be the last Monday of the previous month    let startingDateOfCalendar = this.getStartDateForCalendar(day);    // dateToAdd is an intermediate variable that will get increased    // in the following for loop    let dateToAdd = startingDateOfCalendar;    // ok since we have our starting date then we get the next 41 days     // that we need to add in our calendar array    // 41 cause our calendar will show 6 weeks and MATH say that    // 6 weeks * 7 days = 42!!    for (var i = 0; i < 42; i++) {      this.calendar.push(new CalendarDay(new Date(dateToAdd)));      dateToAdd = new Date(dateToAdd.setDate(dateToAdd.getDate() + 1));    }  }  private getStartDateForCalendar(selectedDate: Date){    // for the day we selected let's get the previous month last day    let lastDayOfPreviousMonth = new Date(selectedDate.setDate(0));    // start by setting the starting date of the calendar same as the last day of previous month    let startingDateOfCalendar: Date = lastDayOfPreviousMonth;    // but since we actually want to find the last Monday of previous month    // we will start going back in days intil we encounter our last Monday of previous month    if (startingDateOfCalendar.getDay() != 1) {      do {        startingDateOfCalendar = new Date(startingDateOfCalendar.setDate(startingDateOfCalendar.getDate() - 1));      } while (startingDateOfCalendar.getDay() != 1);    }    return startingDateOfCalendar;  }

4th let's add some HTML and CSS to actually start displaying our calendar

In the HTML you will see that I'm using a pipe named chunk I'll explain the use of it and the code in a bit

<table class='calendar-table' *ngIf="calendar">  <thead>    <tr>      <th>Monday</th>      <th>Tuesday</th>      <th>Wednesday</th>      <th>Thursday</th>      <th>Friday</th>      <th>Saturday</th>      <th>Sunday</th>    </tr>  </thead>  <tbody>    <tr *ngFor="let row of calendar | chunk: 7; let i = index">      <td class="calendar-day" [ngClass]="{'past-date': c.isPastDate, 'today': c.isToday}" *ngFor="let c of row; let j = index">        <div class="calendar-day-header" [ngClass]="{'blue-date': c.isToday}"><strong>{{c.date.getDate()}}</strong> <strong *ngIf="c.isToday || (i==0 && j==0) || (c.date.getDate() == 1)"> {{monthNames[c.date.getMonth()]}}</strong></div>      </td>    </tr>  </tbody></table>
.calendar-table {  border-collapse: collapse;  width: 100%;  max-width: 100%;  margin-bottom: 1rem;  border: 1px solid #dee2e6;  background-color: #fff;}.calendar-table thead th {  vertical-align: bottom;  border-bottom: 2px solid #dee2e6;  width: 14.2%;}.calendar-table td, .calendar-table th {  border: 1px solid #dee2e6;}.calendar-table td, .calendar-table th {  padding: .75rem;  vertical-align: top;  border-top: 1px solid #dee2e6;}.calendar-day {  height: 12vh;  max-height: 12vh;  cursor: pointer;}.calendar-items-wrapper {  margin-left: -10px;  margin-right: -10px;  overflow-y: auto;  max-height: calc(100% - 20px);}.calendar-day.past-date {  background-color: rgb(248, 248, 248);}.calendar-day:hover {  background-color: rgb(248, 248, 248);}.blue-date {  color: rgb(16, 110, 190);}

5th now it's time to explain and show the code for the chunk pipe

Since our calendar array has 42 elements but we want to show 7 elements in each row the chunk pipe will create an array with 6 arrays inside one array for each week.

@Pipe({  name: 'chunk'})export class ChunkPipe implements PipeTransform {  transform(calendarDaysArray: any, chunkSize: number): any {    let calendarDays = [];    let weekDays = [];    calendarDaysArray.map((day,index) => {        weekDays.push(day);        // here we need to use ++ in front of the variable else index increase         //will happen after the evaluation but we need it to happen BEFORE        if (++index % chunkSize  === 0) {          calendarDays.push(weekDays);          weekDays = [];        }    });    return calendarDays;  }}

This post was written with love


Original Link: https://dev.to/rickystam/how-to-build-a-full-screen-calendar-like-outlook-in-angular-5dcg

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To