diff --git a/projects/igniteui-angular/src/lib/calendar/calendar-base.ts b/projects/igniteui-angular/src/lib/calendar/calendar-base.ts index 94f0a85d2a0..548651b0dae 100644 --- a/projects/igniteui-angular/src/lib/calendar/calendar-base.ts +++ b/projects/igniteui-angular/src/lib/calendar/calendar-base.ts @@ -172,6 +172,11 @@ export class IgxCalendarBaseDirective implements ControlValueAccessor { */ protected _deselectDate: boolean; + /** + * @hidden + */ + private _invokeOnChange = true; + /** * @hidden */ @@ -690,7 +695,9 @@ export class IgxCalendarBaseDirective implements ControlValueAccessor { * @hidden */ public writeValue(value: Date | Date[]) { + this._invokeOnChange = false; this.value = value; + this._invokeOnChange = true; } /** @@ -760,7 +767,9 @@ export class IgxCalendarBaseDirective implements ControlValueAccessor { private selectSingle(value: Date) { if (!isEqual(this.selectedDates?.at(0), value)) { this.selectedDates = [this.getDateOnly(value)]; - this._onChangeCallback(this.selectedDates.at(0)); + if (this._invokeOnChange) { + this._onChangeCallback(this.selectedDates.at(0)); + } } } @@ -773,7 +782,9 @@ export class IgxCalendarBaseDirective implements ControlValueAccessor { if (this.selectedDates !== null && this.getDateOnlyInMs(value as Date) === this.getDateOnlyInMs(this.selectedDates.at(0))) { this.selectedDates = null; - this._onChangeCallback(this.selectedDates); + if (this._invokeOnChange) { + this._onChangeCallback(this.selectedDates); + } } } @@ -849,7 +860,9 @@ export class IgxCalendarBaseDirective implements ControlValueAccessor { this.selectedDates = this.selectedDates.filter(d => !this.isDateDisabled(d)); this.selectedDates.sort((a: Date, b: Date) => a.valueOf() - b.valueOf()); - this._onChangeCallback(this.selectedDates); + if (this._invokeOnChange) { + this._onChangeCallback(this.selectedDates); + } } /** diff --git a/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts b/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts index 9da0f57cb38..c36c5365c50 100644 --- a/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts +++ b/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts @@ -7,7 +7,7 @@ import { waitForAsync, ComponentFixture, } from "@angular/core/testing"; -import { FormsModule } from "@angular/forms"; +import { FormControl, FormGroup, FormsModule, ReactiveFormsModule } from "@angular/forms"; import { By } from "@angular/platform-browser"; import { NoopAnimationsModule } from "@angular/platform-browser/animations"; @@ -3018,6 +3018,34 @@ describe("IgxCalendar - ", () => { })); }); }); + + describe("Forms - ", () => { + let fixture: ComponentFixture; + let component: IgxCalendarReactiveFormsComponent; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [ + NoopAnimationsModule, + ReactiveFormsModule, + FormsModule, + IgxCalendarReactiveFormsComponent] + }).compileComponents(); + + fixture = TestBed.createComponent(IgxCalendarReactiveFormsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it("Should not throw an error when form is recreated - issue #16033", () => { + expect(component.formContext).toBeTruthy(); + expect(component.formContext.get("orderDate")).toBeTruthy(); + expect(() => { + component.resetForm(); + fixture.detectChanges(); + }).not.toThrow(); + }); + }); }); @Component({ @@ -3086,6 +3114,32 @@ export class IgxCalendarValueComponent { public value = new Date(2020, 7, 13); } +@Component({ + template: `
+ +
`, + imports: [IgxCalendarComponent, ReactiveFormsModule, FormsModule] +}) +export class IgxCalendarReactiveFormsComponent { + @ViewChild(IgxCalendarComponent, { static: true }) + public calendar: IgxCalendarComponent; + public formContext: FormGroup; + + constructor() { + this.createForm(); + } + + private createForm() { + this.formContext = new FormGroup({ + orderDate: new FormControl(new Date()), + }); + } + + public resetForm() { + this.createForm(); + } +} + class DateTester { // tests whether a date is disabled or not public static testDatesAvailability(