Reputation: 35
I am working on an Angular project, where an employee will login and then choose a month from an Angular date picker. A table will popup containing the day of the month chosen and under each day an input where he will enter 1 or 0 ( if he worked that day or not ),
my problem is: I don't know how to disable Saturday's and Sunday's inputs + holidays.
Holidays I can have theme by consuming an Api ( public and for free ) of the government of France bellow this you will find a note where I further explain what my app does.
my ts file :
import { DatePipe } from '@angular/common';
import { HttpErrorResponse } from '@angular/common/http';
import { Component } from '@angular/core';
import { FormArray, FormBuilder, FormControl, FormGroup } from '@angular/forms';
import { ApiService } from './api.service';
import {
MomentDateAdapter,
MAT_MOMENT_DATE_ADAPTER_OPTIONS,
} from '@angular/material-moment-adapter';
import {
DateAdapter,
MAT_DATE_FORMATS,
MAT_DATE_LOCALE,
} from '@angular/material/core';
import { MatDatepicker } from '@angular/material/datepicker';
import { MatDatepickerInputEvent } from '@angular/material/datepicker';
import * as moment from 'moment';
import { Moment } from 'moment';
export const MY_FORMATS = {
parse: {
dateInput: 'MM/YYYY',
},
display: {
dateInput: 'MM/YYYY',
monthYearLabel: 'MMM YYYY',
dateA11yLabel: 'LL',
monthYearA11yLabel: 'MMMM YYYY',
},
};
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
providers: [
{
provide: DateAdapter,
useClass: MomentDateAdapter,
deps: [MAT_DATE_LOCALE, MAT_MOMENT_DATE_ADAPTER_OPTIONS],
},
{ provide: MAT_DATE_FORMATS, useValue: MY_FORMATS },
],
})
export class AppComponent {
joursFeries: any;
annee: number = 2022;
totale: number = 0;
form!: FormGroup;
i!: number;
monthDates: String[] = [];
yearSelected!: number;
monthSelected!: number;
daysOfMonth!: number;
daysArray!: FormGroup;
constructor(
public datePipe: DatePipe,
private fb: FormBuilder,
private api: ApiService
) {}
ngOnInit(): void {
let today = new Date();
let todayMonth = today.getMonth() + 1;
let todayYear = today.getFullYear();
const month = Number(todayMonth);
const year = Number(todayYear);
this.monthDates = this.getDaysArray(year, month);
this.daysOfMonth = this.monthDates.length;
this.form = this.fb.group({
year,
month,
days: this.fb.array([]),
});
for (this.i = 0; this.i < this.daysOfMonth; this.i++) {
this.addDay();
}
this.api.getJoursFeries(year).subscribe(
(data: JSON) => {
this.joursFeries = data;
console.log(this.joursFeries);
// console.log(data);
},
(error: HttpErrorResponse) => {
console.log(error);
}
);
}
getDaysArray = (year: number, month: number) => {
const names = Object.freeze([
'Sun',
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
]);
const date = new Date(year, month - 1, 1);
const result = [];
while (date.getMonth() == month - 1) {
result.push(`${date.getDate()}
${names[date.getDay()]}`);
date.setDate(date.getDate() + 1);
}
return result;
};
date = new FormControl(moment());
setMonthAndYear(
normalizedMonthAndYear: Moment,
datepicker: MatDatepicker<Moment>
) {
const ctrlValue = this.date.value;
ctrlValue.month(normalizedMonthAndYear.month());
ctrlValue.year(normalizedMonthAndYear.year());
this.date.setValue(ctrlValue);
datepicker.close();
}
dateChanged($event: MatDatepickerInputEvent<Date>) {
let monthChosen = moment($event.target.value).format('MM');
let yearChosen = moment($event.target.value).format('yyyy');
let month = Number(monthChosen);
let year = Number(yearChosen);
this.monthDates = this.getDaysArray(year, month);
this.daysOfMonth = this.monthDates.length;
const arr = <FormArray>this.form.controls['days'];
arr.controls = [];
this.form.controls['month'].setValue(month);
this.form.controls['year'].setValue(year);
for (this.i = 0; this.i < this.daysOfMonth; this.i++) {
this.addDay();
}
this.api.getJoursFeries(year).subscribe(
(data: JSON) => {
this.joursFeries = data;
console.log(this.joursFeries);
},
(error: HttpErrorResponse) => {
console.log(error);
}
);
}
get days(): FormArray {
return this.form.get('days') as FormArray;
}
addDay(): void {
this.days.push(new FormControl('0'));
}
editDaysWorked() {
console.log('Edit Days Worked');
this.totaleDays();
}
totaleDays() {
for (this.i = 0; this.i < this.form.value.length; this.i++) {
this.totale = this.totale + this.form.value[this.i];
}
}
}
my css file :
.fixTop {
margin-top: 100px;
margin-bottom: 100px;
margin-right: 100px;
margin-left: 100px;
}
.form-control {
/* padding: 30%; */
padding-left: 10px;
padding-right: 2px;
size: 1;
}
.fixTable {
margin-top: 50px;
margin-right: 300px;
}
.top {
margin-top: 100px;
}
.aaa{
margin-inline: 15%;
}
.example-month-picker .mat-calendar-period-button {
pointer-events: none;
}
.example-month-picker .mat-calendar-arrow {
display: none;
}
.right {
margin-left: 200px;
}
.c5 {
background-color: blue;
}
my html file :
<div class="ms-5 mx-5 col-1">
<mat-form-field appearance="outline">
<mat-label>Month and Year</mat-label>
<input
matInput
[matDatepicker]="dp"
[formControl]="date"
(dateChange)="dateChanged($event)"
/>
<mat-datepicker-toggle matSuffix [for]="dp"></mat-datepicker-toggle>
<mat-datepicker #dp startView="year" panelClass="example-month-picker">
</mat-datepicker>
</mat-form-field>
</div>
<div>
<form [formGroup]="form">
<div class="mt-5" formArrayName="days">
<div class="d-flex mx-5 me-5 mb-5">
<table class="table">
<thead>
<tr>
<th scope="col" *ngFor="let date of monthDates">{{ date }}</th>
</tr>
</thead>
<tbody>
<tr>
<td
*ngFor="
let j of [].constructor(this.daysOfMonth);
let day;
of: days.controls;
let i = index
"
>
<input
class="form-control"
[id]="i"
type="text"
formControlName="{{ i }}"
name="day"
[value]="form.value.days[i]"
size="1"
maxlength="1"
/>
</td>
</tr>
</tbody>
</table>
<br />
</div>
<div [align]="'center'">
<button mat-raised-button color="primary">save</button>
<button
class="ms-3"
mat-raised-button
(click)="editDaysWorked()"
color="warn"
>
edit
</button>
</div>
</div>
</form>
</div>
{{ joursFeries | json }}
my service file :
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root',
})
export class ApiService {
private apiBaseUrl = 'https://calendrier.api.gouv.fr/jours-feries/metropole';
constructor(private http: HttpClient) {}
getJoursFeries(annee: number): Observable<any> {
return this.http.get<any>(`${this.apiBaseUrl}/${annee}.json`);
}
}
After the employee login to his page he will find an Angular datePicker and a table, the table contains the days of the current month he is in, under each day there is an input where he can enter 1 if he worked that day or 0 if not, default value is 0 , after he fill the table with the correct values he can click on save and the data will be stored on a database, if he want to change the month he will click on the datpicker and change the dates
Upvotes: 1
Views: 179
Reputation: 130
The MatDatepicker
API provides a filter capability. You can use this to filter out weekends and holidays. API Docs
Adding the [matDatepickerFilter]="myFilterFunc"
property to your input for the datepicker, will allow you to apply a filter of your choosing. myFilterFunc
, in this case, would be a function in your component class that takes a date and returns true or false.
Ex: filtering weekends
myFilterFunc = (d: Date | null): boolean => {
const day = (d || new Date()).getDay();
// Prevent Saturday and Sunday from being selected.
return day !== 0 && day !== 6;
};
You can use your service logic to pull holidays in advance and then integrate that into this kind of filter function.
Upvotes: 1