Home > Blockchain >  How to remove MAT_DATE_RANGE_SELECTION_STRATEGY dynamically in angular
How to remove MAT_DATE_RANGE_SELECTION_STRATEGY dynamically in angular

Time:11-01

I am trying to implement a datepicker in angular with custom MAT_DATE_RANGE_SELECTION_STRATEGY. Which allows user to select a 14 day range.

Daterange picker

Using below code (taken right out of angular documentation) to implement custom strategy

@Injectable()
export class FourteenDayRangeSelectionStrategy<D> implements MatDateRangeSelectionStrategy<D> {
  constructor(private _dateAdapter: DateAdapter<D>) {}

  selectionFinished(date: D | null): DateRange<D> {
    return this._createFourteeDayRange(date);
  }

  createPreview(activeDate: D | null): DateRange<D> {
    return this._createFourteeDayRange(activeDate);
  }

  private _createFourteeDayRange(date: D | null): DateRange<D> {
    if (date) {
      const start = this._dateAdapter.addCalendarDays(date, 0);
      const end = this._dateAdapter.addCalendarDays(date, 13);
      return new DateRange<D>(start, end);
    }

    return new DateRange<D>(null, null);
  }
}

and injecting it in the component as below.

@Component({
  selector: 'app-awesomecomponent',
  templateUrl: './awesomecomponent.component.html',
  styleUrls: ['./awesomecomponent.component.css'],
  providers: [{
    provide: MAT_DATE_RANGE_SELECTION_STRATEGY,
    useClass: FourteenDayRangeSelectionStrategy
  }]
})

However when the user selects the Allow Custom Date Range check box (shown in above image), I would want the custom strategy to be disabled and allow user to choose any date range.

How can I achieve this functionality? I assume, we need to dynamically remove below from component to allow any date selection. However I do not know how to do this.

providers: [{
    provide: MAT_DATE_RANGE_SELECTION_STRATEGY,
    useClass: FourteenDayRangeSelectionStrategy
  }]

Please help.

CodePudding user response:

You has the source of MatDateRangeSelectionStrategy in github So your can use a variable to make active or not the strategy.

export class FourteenDaySelectionStrategy<D>
  implements MatDateRangeSelectionStrategy<D>
{
  constructor(private _dateAdapter: DateAdapter<D>) {}
  off: boolean = false; //--use a variable "off"
  selectionFinished(date: D | null, currentRange: DateRange<D>): DateRange<D> {
    if (!this.off) return this._createFourteenDayRange(date);

    //see that al the code below is the code of the github
    let { start, end } = currentRange;

    if (start == null) {
      start = date;
    } else if (
      end == null &&
      date &&
      this._dateAdapter.compareDate(date, start) >= 0
    ) {
      end = date;
    } else {
      start = date;
      end = null;
    }

    return new DateRange<D>(start, end);
  }

  createPreview(
    activeDate: D | null,
    currentRange: DateRange<D>
  ): DateRange<D> {
    if (!this.off) return this._createFourteenDayRange(activeDate);

    //see that al the code below is the code of the github
    let start: D | null = null;
    let end: D | null = null;

    if (currentRange.start && !currentRange.end && activeDate) {
      start = currentRange.start;
      end = activeDate;
    }

    return new DateRange<D>(start, end);
  }

  private _createFourteenDayRange(date: D | null): DateRange<D> {
    if (date) {
      const start = date;
      const end = this._dateAdapter.addCalendarDays(date, 14);
      return new DateRange<D>(start, end);
    }

    return new DateRange<D>(null, null);
  }

Now, you need inject the MatDateRangeSelection and use a getter to change the value of the variable off

  constructor(
    @Inject(MAT_DATE_RANGE_SELECTION_STRATEGY)
    private rg: FourteenDaySelectionStrategy<any>
  ) {}
  get customRange() {
    return this.rg.off;
  }
  set customRange(value) {
    this.rg.off = value;
  }

A checkbox with [(ngModel)] complete the code

See the stackblitz

  • Related