Reputation: 3449
Im looking to style specific days in the datepicker object but I cant seem to get access to the DOM elements from the calendar. I tried using a view child, but that only gave me access to the picker element, not the calendar that gets created when click on the picker.
I have also tried adding a panel class to the date picker and trying to select on that, but it also doesnt seem to work. https://stackblitz.com/edit/angular-zjt5wz-ehdbdt?file=app/datepicker-start-view-example.ts
Ideally, I want to apply a class to every day that meets a specific criteria. For example, style all days prior to the selected day as yellow. How can I go about doing this?
Upvotes: 1
Views: 4225
Reputation: 7129
It can be done through css. Here for example I am chsnging the color of dates of the weekends:
.mat-calendar-table {
td:first-child > .mat-calendar-body-cell-content {
color: red;
}
td:nth-child(7) > .mat-calendar-body-cell-content {
color: red !important;
}
}
Upvotes: 0
Reputation: 1715
You are looking for the @Input() dateClass: (date: D) => MatCalendarCellCssClasses
property of mat-datepicker
. You provide a function that takes a date param and returns a css class. Use the function to decide which dates should have the css class.
Every time the user changes the display, i.e. moves to another month, the function is called for every date in the display.
And finally, you may need to include the css class in a global file and not in the css file associated with your component (research "View Encapsulation" for more).
Upvotes: 3
Reputation: 34445
That's because when the opened
event fires, the view does not contain the DOM elements for the calendar yet.
You can wrap your code in a setTimeout
as a workaround
streamOpened(event) {
setTimeout(()=>{
let elements = document.querySelectorAll('.endDate');
//here elements will not be empty
});
Edit
Following your comment, the material datepicker API has no event for listening to changes to displayed date range. As a hack, you could try manually listening to next/previous button click like this
constructor(private renderer:Renderer2){}
//...
let nextBtn = document.querySelectorAll('.mat-calendar-next-button')[0];
this.renderer.listen(nextBtn, 'click', ()=>
{
console.log('click on next')
//Re-run logic here (probably in timeout again...)
})
Edit 2
Following your 2nd comment, here is an example that binds refresh to all calendar button clicks. That should be enough to get you going. You'll probably need to add more listener to other calendar events though
Basically, you can try listening to all click events
let x = elements[0].querySelectorAll('.mat-calendar-body-cell');
x.forEach(y => {
let c = new Date(y.getAttribute("aria-label"));
if(c < this.startDate)
{
y.classList.add('newClass');
}
});
Upvotes: 4