Search code examples
javascriptjquerynode.jsangularangular8

How to display half year based on year selection and disable half year for future years Angular 8


I have year and half year dropdown in UI,Based on selected year i want to change half year dropdown Can anyone help me to implement below logic to achieve my expected output

For ex - If user selected 2021 or 2022 or 2023 in the dropdown than it will display option1 H1(Jan-June), option2 H2(July-Dec) both bcz till 2023 all years are completed.

And for future years or for every new year for ex 2024 or 2025, options H1(Jan-June) only enables when july month start and option2 H2(July-Dec) only enables when January of the new year starts.

Expected output

2022 Display option1 H1(Jan-June) and  option2 H2(July-Dec)
2023 Display option1 H1(Jan-June) and  option2 H2(July-Dec)
2024 Enable option1 H1(Jan-June) When July month starts and option2 H2(July-Dec) enables when January of 2025 starts
like wise....

Below is my code for dropdown and half year slicer

<mat-select>
                        <mat-option *ngFor="let year of years" [value]="year">
                            {{year}}
                        </mat-option>
                    </mat-select>

                     <mat-select class="lineDet subfamilySelect lossSubMatCls" placeholder="Select half Year">
                        <mat-option *ngFor="let type of halfYearlyOptions" [value]="type"> {{type}}
                        </mat-option>
                    </mat-select>

                **Component**

years: number[] = [];
halfYearlyOptions = ['H1 Jan-June', 'H2 July-Dec'];
ngOnInit(){
    for (let date = new Date(2020, 6, 1); date < now; date = new Date(date.setFullYear(date.getFullYear() + 1))) {
        this.years.push(date.getFullYear());
      }
}

Solution

  • You can use the selectionChange to listen for the latest value, then apply the logic to filter the dropdown based on the conditions mentioned!

    Code explanation on comments in the code!

    import { CommonModule } from '@angular/common';
    import { Component } from '@angular/core';
    import { bootstrapApplication } from '@angular/platform-browser';
    import { MatSelectModule } from '@angular/material/select';
    import 'zone.js';
    import { provideAnimations } from '@angular/platform-browser/animations';
    
    @Component({
      selector: 'app-root',
      standalone: true,
      imports: [CommonModule, MatSelectModule],
      template: `
        <mat-select (selectionChange)="selectionChange($event)">
            <mat-option *ngFor="let year of years" [value]="year">
                {{year}}
            </mat-option>
        </mat-select>
    
          <mat-select class="lineDet subfamilySelect lossSubMatCls" placeholder="Select half Year">
            <mat-option *ngFor="let type of halfYearlyOptions" [value]="type"> {{type}}
            </mat-option>
        </mat-select>
      `,
    })
    export class App {
      years: number[] = [];
      // take a backup of the original array, since we need to refernce these values conditionally
      halfYearlyOptionsOriginal: Array<string> = ['H1 Jan-June', 'H2 July-Dec'];
      // use this array to conditionally add values based on logic
      halfYearlyOptions: Array<string> = [];
      ngOnInit() {
        const now = new Date();
        for (
          // I changed this to show 2024, you can revert it if needed
          let date = new Date(2020, 0, 1);
          date < now;
          date = new Date(date.setFullYear(date.getFullYear() + 1))
        ) {
          console.log(date);
          this.years.push(date.getFullYear());
        }
      }
    
      selectionChange(year: any) {
        // get the year from the event coming from mat select
        const yearInput = year && year.value;
        // get the todays date
        const currentTime = new Date();
        // get todays year
        var nowYear = currentTime.getFullYear();
        // get todays month, since zero index add 1
        var nowMonth = currentTime.getMonth() + 1;
        // your logic goes here, we need to check month is not before 7 and current year
        if (yearInput === nowYear && nowMonth <= 6) {
          // assign no items
          this.halfYearlyOptions = [];
          // your logic goes here, we need to check month is after 6 and current year
        } else if (yearInput === nowYear && nowMonth > 6) {
          // assign only the first item
          this.halfYearlyOptions = [this.halfYearlyOptionsOriginal[0]];
        } else {
          // all other scenarios assign all items!
          this.halfYearlyOptions = [...this.halfYearlyOptionsOriginal];
        }
      }
    }
    
    bootstrapApplication(App, {
      providers: [provideAnimations()],
    });
    

    stackblitz