Skip to content

Commit 45db584

Browse files
authored
Merge pull request #15998 from IgniteUI/ikitanov-fix/15989-20.0.x
Sync aria-required with required state - 20.0.x
2 parents 33f258f + 0fb975a commit 45db584

File tree

2 files changed

+20
-26
lines changed

2 files changed

+20
-26
lines changed

projects/igniteui-angular/src/lib/select/select.component.spec.ts

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,7 @@ describe('igxSelect', () => {
424424
expect(inputElement.nativeElement.getAttribute('aria-haspopup')).toEqual('listbox');
425425
expect(inputElement.nativeElement.getAttribute('aria-labelledby')).toEqual(labelID);
426426
expect(dropdownListElement.nativeElement.getAttribute('aria-labelledby')).toEqual(labelID);
427+
expect(inputElement.nativeElement.getAttribute('aria-required')).toEqual('false');
427428
expect(inputElement.nativeElement.getAttribute('aria-owns')).toEqual(select.listId);
428429
expect(inputElement.nativeElement.getAttribute('aria-expanded')).toEqual('false');
429430
expect(toggleBtn.nativeElement.getAttribute('aria-hidden')).toEqual('true');
@@ -574,6 +575,7 @@ describe('igxSelect', () => {
574575
const dom = fix.debugElement;
575576
const selectComp = fix.componentInstance.select;
576577
const formGroup: UntypedFormGroup = fix.componentInstance.reactiveForm;
578+
inputElement = dom.query(By.css('.' + CSS_CLASS_INPUT));
577579
let inputGroupIsRequiredClass = dom.query(By.css('.' + CSS_CLASS_INPUT_GROUP_REQUIRED));
578580
let inputGroupInvalidClass = dom.query(By.css('.' + CSS_CLASS_INPUT_GROUP_INVALID));
579581
// interaction test - expect actual asterisk
@@ -583,6 +585,7 @@ describe('igxSelect', () => {
583585
expect(asterisk).toBe('"*"');
584586
expect(inputGroupIsRequiredClass).toBeDefined();
585587
expect(inputGroupIsRequiredClass).not.toBeNull();
588+
expect(inputElement.nativeElement.getAttribute('aria-required')).toEqual('true');
586589

587590
// 2) check that input group's --invalid class is NOT applied
588591
expect(inputGroupInvalidClass).toBeNull();
@@ -604,11 +607,13 @@ describe('igxSelect', () => {
604607
inputGroupIsRequiredClass = dom.query(By.css('.' + CSS_CLASS_INPUT_GROUP_REQUIRED));
605608
expect(inputGroupIsRequiredClass).not.toBeNull();
606609
expect(inputGroupIsRequiredClass).not.toBeUndefined();
610+
expect(inputElement.nativeElement.getAttribute('aria-required')).toEqual('true');
607611

608612
// 3) Check if the input group's --invalid and --required classes are removed when validator is dynamically cleared
609613
fix.componentInstance.removeValidators(formGroup);
610614
fix.detectChanges();
611615
tick();
616+
expect(inputElement.nativeElement.getAttribute('aria-required')).toEqual('false');
612617

613618
inputGroupIsRequiredClass = dom.query(By.css('.' + CSS_CLASS_INPUT_GROUP_REQUIRED));
614619
const selectFormReference = fix.componentInstance.reactiveForm.controls.optionsSelect;
@@ -642,6 +647,7 @@ describe('igxSelect', () => {
642647
// Re-add all Validators
643648
fix.componentInstance.addValidators(formGroup);
644649
fix.detectChanges();
650+
expect(inputElement.nativeElement.getAttribute('aria-required')).toEqual('true');
645651

646652
inputGroupIsRequiredClass = dom.query(By.css('.' + CSS_CLASS_INPUT_GROUP_REQUIRED));
647653
expect(inputGroupIsRequiredClass).toBeDefined();
@@ -650,24 +656,6 @@ describe('igxSelect', () => {
650656
// interaction test - expect actual asterisk
651657
asterisk = window.getComputedStyle(dom.query(By.css('.' + CSS_CLASS_INPUT_GROUP_LABEL)).nativeElement, ':after').content;
652658
expect(asterisk).toBe('"*"');
653-
654-
// 4) Should NOT remove asterisk, when remove validators on igxSelect with required HTML attribute set(edge case)
655-
// set required HTML attribute
656-
inputGroup.parent.nativeElement.setAttribute('required', '');
657-
// Re-add all Validators
658-
fix.componentInstance.addValidators(formGroup);
659-
fix.detectChanges();
660-
// update and clear validators
661-
fix.componentInstance.removeValidators(formGroup);
662-
fix.detectChanges();
663-
tick();
664-
// expect asterisk
665-
asterisk = window.getComputedStyle(dom.query(By.css('.' + CSS_CLASS_INPUT_GROUP_LABEL)).nativeElement, ':after').content;
666-
expect(asterisk).toBe('"*"');
667-
inputGroupIsRequiredClass = dom.query(By.css('.' + CSS_CLASS_INPUT_GROUP_REQUIRED));
668-
expect(inputGroupIsRequiredClass).toBeDefined();
669-
expect(inputGroupIsRequiredClass).not.toBeNull();
670-
expect(inputGroupIsRequiredClass).not.toBeUndefined();
671659
}));
672660

673661
it('should update validity state when programmatically setting errors on reactive form controls', fakeAsync(() => {

projects/igniteui-angular/src/lib/select/select.component.ts

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -606,19 +606,25 @@ export class IgxSelectComponent extends IgxDropDownComponent implements IgxSelec
606606

607607
protected manageRequiredAsterisk(): void {
608608
const hasRequiredHTMLAttribute = this.elementRef.nativeElement.hasAttribute('required');
609+
let isRequired = false;
610+
609611
if (this.ngControl && this.ngControl.control.validator) {
610-
// Run the validation with empty object to check if required is enabled.
611612
const error = this.ngControl.control.validator({} as AbstractControl);
612-
this.inputGroup.isRequired = error && error.required;
613-
this.cdr.markForCheck();
613+
isRequired = !!(error && error.required);
614+
}
615+
616+
this.inputGroup.isRequired = isRequired;
614617

615-
// If validator is dynamically cleared and no required HTML attribute is set,
616-
// reset label's required class(asterisk) and IgxInputState #6896
617-
} else if (this.inputGroup.isRequired && this.ngControl && !this.ngControl.control.validator && !hasRequiredHTMLAttribute) {
618+
if (this.input?.nativeElement) {
619+
this.input.nativeElement.setAttribute('aria-required', isRequired.toString());
620+
}
621+
622+
// Handle validator removal case
623+
if (!isRequired && !hasRequiredHTMLAttribute) {
618624
this.input.valid = IgxInputState.INITIAL;
619-
this.inputGroup.isRequired = false;
620-
this.cdr.markForCheck();
621625
}
626+
627+
this.cdr.markForCheck();
622628
}
623629

624630
private setSelection(item: IgxDropDownItemBaseDirective) {

0 commit comments

Comments
 (0)