'How to disable specific inputs that match an api in angular

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

my stack blitz

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



Solution 1:[1]

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.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 mfaith