i have a multiple startDate and endDate from my data and i want to use that for disabled date range in datePicker Material of Angular.
I see this issue :link, but in the example is for two table, in my case i have a lot of table, so i begin a code with a loop but i don't know how to use it
this is my code :
import { formatDate } from '@angular/common';
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { map, Observable } from 'rxjs';
import { Booking } from 'src/app/core/models/booking.model';
import { BookingService } from 'src/app/core/services/booking.service';
@Component({
selector: 'app-booking',
templateUrl: './booking.component.html',
styleUrls: ['./booking.component.scss'],
})
export class BookingComponent implements OnInit {
idAccommodation!: number;
bookingAccommodation$!: Observable<Booking[]>;
dateBooking: Array<Array<any>> = [];
dateDisabled!: any;
constructor(
private activedRoute: ActivatedRoute,
private bookingService: BookingService
) {}
ngOnInit(): void {
this.idAccommodation = +this.activedRoute.snapshot.params['id'];
this.bookingService
.getBookingByIdAccommodation(this.idAccommodation)
.pipe(map((res: any) => res['hydra:member']))
.subscribe({
next: (res: any) => {
res.forEach((element: any) => {
this.dateBooking.push([
new Date(element.startDate),
new Date(element.endDate),
]);
});
this.dateBooking.forEach((element) => {
element.forEach((date) => {
console.log(date);
});
});
this.dateDisabled = (date: Date | null): any => {
return (
!(
date! >= this.dateBooking[1][0] &&
date! <= this.dateBooking[1][1]
) && date! >= new Date()
);
};
},
});
}
}
Thanks for your helping 👍
When you work with Date javascript object you need be carefull
A mat-datepicker return you a date object of type, e.g.
Mon Sep 19 2022 00:00:00 GMT+0200
When you use, e.g.
new Date('2022-08-24')
//you get
Date Wed Aug 24 2022 02:00:00 GMT+0200
See how add the "02:00:00" -because I'm in GTM+0200. So the first you need is that your range becomes in the way 00:00:00 using setHours
res.forEach((element: any) => {
const el=[
new Date(element.startDate),
new Date(element.endDate),
]
el[0].setHours(setHours(0, 0, 0, 0))
el[1].setHours(setHours(0, 0, 0, 0))
this.dateBooking.push(el);
});
}
Equal you need take carefull with "today". So in ngOnInit you can use
ngOnInit() {
//see how use setHours also in today
const today = new Date();
today.setHours(0, 0, 0, 0);
this.dateDisabled = (date: Date | null): any => {
if (date! < today) return false;
for (let i = 0; i < this.dateBooking.length; i++) {
if (date! >= this.dateBooking[i][0] && date! <= this.dateBooking[i][1])
return false;
}
return true;
};
//or
this.dateDisabled = (date: Date | null): any => {
return (
date! >= today &&
this.dateBooking.reduce((a, b) => {
return a && (date! < b[0] || date! > b[1]);
}, true)
);
};
}
NOTE: the second approach loop over all the elements of dateBooking. It's looks like slower that the first one but really the time spend (30 days* dateBooking.length) it's not apreciable
see stackblitz
NOTE2: If you need severals "dateDisabled" functions use an array of functions
dateDisabled:((date: Date | null)=>any)[]=[]
// and use
dateDisabledObj[index]=(date: Date | null): any => {...}
Or and object of functions
dateDisabledObj:any={}
// and use
dateDisabledObj[''+id]=(date: Date | null): any => {...}