Skip to content

Commit 5444f84

Browse files
fix(date-picker): apply asterisk when reactive form required validator is set #10120 (#10170)
1 parent e54170b commit 5444f84

File tree

2 files changed

+98
-5
lines changed

2 files changed

+98
-5
lines changed

projects/igniteui-angular/src/lib/date-picker/date-picker.component.spec.ts

Lines changed: 92 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { ComponentFixture, fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing';
2-
import { FormsModule, NgForm, ReactiveFormsModule } from '@angular/forms';
2+
import { FormControl, FormGroup, FormsModule, NgForm, ReactiveFormsModule, Validators } from '@angular/forms';
33
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
44
import { UIInteractions } from '../test-utils/ui-interactions.spec';
55
import {
@@ -33,6 +33,9 @@ const CSS_CLASS_DATE_PICKER = 'igx-date-picker';
3333
const DATE_PICKER_TOGGLE_ICON = 'today';
3434
const DATE_PICKER_CLEAR_ICON = 'clear';
3535

36+
const CSS_CLASS_INPUT_GROUP_REQUIRED = 'igx-input-group--required';
37+
const CSS_CLASS_INPUT_GROUP_INVALID = 'igx-input-group--invalid ';
38+
const CSS_CLASS_INPUT_GROUP_LABEL = 'igx-input-group__label';
3639

3740
describe('IgxDatePicker', () => {
3841
describe('Integration tests', () => {
@@ -44,7 +47,8 @@ describe('IgxDatePicker', () => {
4447
IgxDatePickerTestComponent,
4548
IgxDatePickerNgModelComponent,
4649
IgxDatePickerWithProjectionsComponent,
47-
IgxDatePickerInFormComponent
50+
IgxDatePickerInFormComponent,
51+
IgxDatePickerReactiveFormComponent
4852
],
4953
imports: [IgxDatePickerModule, FormsModule, ReactiveFormsModule,
5054
NoopAnimationsModule, IgxInputGroupModule, IgxCalendarModule,
@@ -193,7 +197,9 @@ describe('IgxDatePicker', () => {
193197
});
194198

195199
describe('NgControl integration', () => {
196-
let fixture: ComponentFixture<IgxDatePickerNgModelComponent | IgxDatePickerInFormComponent>;
200+
let fixture: ComponentFixture<IgxDatePickerNgModelComponent |
201+
IgxDatePickerInFormComponent |
202+
IgxDatePickerReactiveFormComponent>;
197203
let datePicker: IgxDatePickerComponent;
198204

199205
beforeEach(fakeAsync(() => {
@@ -238,6 +244,53 @@ describe('IgxDatePicker', () => {
238244
tick();
239245
expect((datePicker as any).inputDirective.valid).toEqual(IgxInputState.INITIAL);
240246
}));
247+
248+
it('should apply asterix properly when required validator is set dynamically', () => {
249+
fixture = TestBed.createComponent(IgxDatePickerReactiveFormComponent);
250+
fixture.detectChanges();
251+
datePicker = fixture.componentInstance.datePicker;
252+
253+
let inputGroupRequiredClass = fixture.debugElement.query(By.css('.' + CSS_CLASS_INPUT_GROUP_REQUIRED));
254+
let inputGroupInvalidClass = fixture.debugElement.query(By.css('.' + CSS_CLASS_INPUT_GROUP_INVALID));
255+
let asterisk = window.
256+
getComputedStyle(fixture.debugElement.query(By.css('.' + CSS_CLASS_INPUT_GROUP_LABEL)).nativeElement, ':after').
257+
content;
258+
expect(asterisk).toBe('"*"');
259+
expect(inputGroupRequiredClass).toBeDefined();
260+
expect(inputGroupRequiredClass).not.toBeNull();
261+
262+
datePicker.clear();
263+
fixture.detectChanges();
264+
265+
inputGroupInvalidClass = fixture.debugElement.query(By.css('.' + CSS_CLASS_INPUT_GROUP_INVALID));
266+
expect(inputGroupInvalidClass).not.toBeNull();
267+
expect(inputGroupInvalidClass).not.toBeUndefined();
268+
269+
inputGroupRequiredClass = fixture.debugElement.query(By.css('.' + CSS_CLASS_INPUT_GROUP_REQUIRED));
270+
expect(inputGroupRequiredClass).not.toBeNull();
271+
expect(inputGroupRequiredClass).not.toBeUndefined();
272+
273+
(fixture.componentInstance as IgxDatePickerReactiveFormComponent).removeValidators();
274+
fixture.detectChanges();
275+
276+
inputGroupRequiredClass = fixture.debugElement.query(By.css('.' + CSS_CLASS_INPUT_GROUP_REQUIRED));
277+
asterisk = window.
278+
getComputedStyle(fixture.debugElement.query(By.css('.' + CSS_CLASS_INPUT_GROUP_LABEL)).nativeElement, ':after').
279+
content;
280+
expect(inputGroupRequiredClass).toBeNull();
281+
expect(asterisk).toBe('none');
282+
283+
(fixture.componentInstance as IgxDatePickerReactiveFormComponent).addValidators();
284+
fixture.detectChanges();
285+
286+
inputGroupRequiredClass = fixture.debugElement.query(By.css('.' + CSS_CLASS_INPUT_GROUP_REQUIRED));
287+
asterisk = window.
288+
getComputedStyle(fixture.debugElement.query(By.css('.' + CSS_CLASS_INPUT_GROUP_LABEL)).nativeElement, ':after').
289+
content;
290+
expect(inputGroupRequiredClass).toBeDefined();
291+
expect(inputGroupRequiredClass).not.toBeNull();
292+
expect(asterisk).toBe('"*"');
293+
});
241294
});
242295

243296
describe('Projected elements', () => {
@@ -339,6 +392,7 @@ describe('IgxDatePicker', () => {
339392
let overlay: IgxOverlayService;
340393
let mockOverlayEventArgs: OverlayEventArgs & OverlayCancelableEventArgs;
341394
let mockInjector;
395+
let mockCdr;
342396
let mockInputGroup: Partial<IgxInputGroupComponent>;
343397
let datePicker: IgxDatePickerComponent;
344398
let mockDateEditor: any;
@@ -403,6 +457,8 @@ describe('IgxDatePicker', () => {
403457
get: mockNgControl
404458
});
405459

460+
mockCdr = jasmine.createSpyObj('ChangeDetectorRef', ['detectChanges']);
461+
406462
mockCalendar = { selected: new EventEmitter<any>() };
407463
const mockComponentInstance = {
408464
calendar: mockCalendar,
@@ -512,7 +568,7 @@ describe('IgxDatePicker', () => {
512568
},
513569
focus: () => { }
514570
};
515-
datePicker = new IgxDatePickerComponent(elementRef, null, overlay, mockModuleRef, mockInjector, renderer2, null);
571+
datePicker = new IgxDatePickerComponent(elementRef, null, overlay, mockModuleRef, mockInjector, renderer2, null, mockCdr);
516572
(datePicker as any).inputGroup = mockInputGroup;
517573
(datePicker as any).inputDirective = mockInputDirective;
518574
(datePicker as any).dateTimeEditor = mockDateEditor;
@@ -1251,3 +1307,35 @@ export class IgxDatePickerInFormComponent {
12511307

12521308
public date: Date = new Date(2012, 5, 3);
12531309
}
1310+
1311+
@Component({
1312+
template: `
1313+
<form [formGroup]="form">
1314+
<div class="date-picker-wrapper">
1315+
<igx-date-picker formControlName="date" [value]="date">
1316+
<label igxLabel>Date </label>
1317+
</igx-date-picker>
1318+
</div>
1319+
</form>
1320+
`
1321+
})
1322+
export class IgxDatePickerReactiveFormComponent {
1323+
@ViewChild(IgxDatePickerComponent)
1324+
public datePicker: IgxDatePickerComponent;
1325+
1326+
public date: Date = new Date(2012, 5, 3);
1327+
1328+
public form: FormGroup = new FormGroup({
1329+
date: new FormControl(null, Validators.required)
1330+
});
1331+
1332+
public removeValidators() {
1333+
this.form.get('date').clearValidators();
1334+
this.form.get('date').updateValueAndValidity();
1335+
}
1336+
1337+
public addValidators() {
1338+
this.form.get('date').setValidators(Validators.required);
1339+
this.form.get('date').updateValueAndValidity();
1340+
}
1341+
}

projects/igniteui-angular/src/lib/date-picker/date-picker.component.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import {
22
Component, ContentChild, EventEmitter, HostBinding, Input,
33
OnDestroy, Output, ViewChild, ElementRef, Inject, HostListener,
44
NgModuleRef, OnInit, AfterViewInit, Injector, AfterViewChecked, ContentChildren,
5-
QueryList, LOCALE_ID, Renderer2, Optional, PipeTransform
5+
QueryList, LOCALE_ID, Renderer2, Optional, PipeTransform, ChangeDetectorRef
66
} from '@angular/core';
77
import {
88
ControlValueAccessor, NG_VALUE_ACCESSOR, NgControl, AbstractControl,
@@ -481,6 +481,7 @@ export class IgxDatePickerComponent extends PickerBaseDirective implements Contr
481481
private _injector: Injector,
482482
private _renderer: Renderer2,
483483
private platform: PlatformUtil,
484+
private cdr: ChangeDetectorRef,
484485
@Optional() @Inject(DisplayDensityToken) protected _displayDensityOptions?: IDisplayDensityOptions,
485486
@Optional() @Inject(IGX_INPUT_GROUP_TYPE) protected _inputGroupType?: IgxInputGroupType) {
486487
super(element, _localeId, _displayDensityOptions, _inputGroupType);
@@ -750,6 +751,10 @@ export class IgxDatePickerComponent extends PickerBaseDirective implements Contr
750751
if (this._ngControl) {
751752
this._statusChanges$ =
752753
this._ngControl.statusChanges.subscribe(this.onStatusChanged.bind(this));
754+
if (this._ngControl.control.validator) {
755+
this.inputGroup.isRequired = this.required;
756+
this.cdr.detectChanges();
757+
}
753758
}
754759
}
755760

0 commit comments

Comments
 (0)