Skip to content

Commit 2bd0c12

Browse files
committed
fix(material/chips): show required asterisk when using required validator
Similar to angular#23362. Fixes that the required asterisk wasn't being shown when a chip list is required.
1 parent 8424209 commit 2bd0c12

File tree

5 files changed

+43
-14
lines changed

5 files changed

+43
-14
lines changed

src/material-experimental/mdc-chips/chip-grid.spec.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -732,7 +732,7 @@ describe('MDC-based MatChipGrid', () => {
732732
.withContext(`Expected placeholder not to have an asterisk, as control was not required.`)
733733
.toBeNull();
734734

735-
fixture.componentInstance.isRequired = true;
735+
fixture.componentInstance.chipGrid.required = true;
736736
fixture.detectChanges();
737737

738738
requiredMarker = fixture.debugElement.query(By.css('.mdc-floating-label--required'))!;
@@ -741,6 +741,15 @@ describe('MDC-based MatChipGrid', () => {
741741
.toBeNull();
742742
});
743743

744+
it('should mark the component as required if the control has a required validator', () => {
745+
fixture.destroy();
746+
fixture = TestBed.createComponent(InputChipGrid);
747+
fixture.componentInstance.control = new FormControl(undefined, [Validators.required]);
748+
fixture.detectChanges();
749+
750+
expect(fixture.nativeElement.querySelector('.mdc-floating-label--required')).toBeTruthy();
751+
});
752+
744753
it('should blur the form field when the active chip is blurred', fakeAsync(() => {
745754
const formField: HTMLElement = fixture.nativeElement.querySelector('.mat-mdc-form-field');
746755

@@ -1077,8 +1086,7 @@ class FormFieldChipGrid {
10771086
template: `
10781087
<mat-form-field>
10791088
<mat-label>New food...</mat-label>
1080-
<mat-chip-grid #chipGrid
1081-
placeholder="Food" [formControl]="control" [required]="isRequired">
1089+
<mat-chip-grid #chipGrid placeholder="Food" [formControl]="control">
10821090
<mat-chip-row *ngFor="let food of foods" [value]="food.value" (removed)="remove(food)">
10831091
{{ food.viewValue }}
10841092
</mat-chip-row>
@@ -1106,7 +1114,6 @@ class InputChipGrid {
11061114

11071115
separatorKeyCodes = [ENTER, SPACE];
11081116
addOnBlur: boolean = true;
1109-
isRequired: boolean;
11101117

11111118
add(event: MatChipInputEvent): void {
11121119
const value = (event.value || '').trim();

src/material-experimental/mdc-chips/chip-grid.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,13 @@ import {
2727
Self,
2828
ViewEncapsulation
2929
} from '@angular/core';
30-
import {ControlValueAccessor, FormGroupDirective, NgControl, NgForm} from '@angular/forms';
30+
import {
31+
ControlValueAccessor,
32+
FormGroupDirective,
33+
NgControl,
34+
NgForm,
35+
Validators,
36+
} from '@angular/forms';
3137
import {
3238
CanUpdateErrorState,
3339
CanUpdateErrorStateCtor,
@@ -186,12 +192,14 @@ export class MatChipGrid extends _MatChipGridMixinBase implements AfterContentIn
186192
* @docs-private
187193
*/
188194
@Input()
189-
get required(): boolean { return this._required; }
195+
get required(): boolean {
196+
return this._required ?? this.ngControl?.control?.hasValidator(Validators.required) ?? false;
197+
}
190198
set required(value: boolean) {
191199
this._required = coerceBooleanProperty(value);
192200
this.stateChanges.next();
193201
}
194-
protected _required: boolean = false;
202+
protected _required: boolean | undefined;
195203

196204
/**
197205
* Implemented as part of MatFormFieldControl.

src/material/chips/chip-list.spec.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -857,7 +857,7 @@ describe('MatChipList', () => {
857857
.withContext(`Expected placeholder not to have an asterisk, as control was not required.`)
858858
.toBeNull();
859859

860-
fixture.componentInstance.isRequired = true;
860+
fixture.componentInstance.chipList.required = true;
861861
fixture.detectChanges();
862862

863863
requiredMarker = fixture.debugElement.query(By.css('.mat-form-field-required-marker'))!;
@@ -866,6 +866,13 @@ describe('MatChipList', () => {
866866
.not.toBeNull();
867867
});
868868

869+
it('should mark the component as required if the control has a required validator', () => {
870+
fixture.componentInstance.control = new FormControl(undefined, [Validators.required]);
871+
fixture.detectChanges();
872+
873+
expect(fixture.nativeElement.querySelector('.mat-form-field-required-marker')).toBeTruthy();
874+
});
875+
869876
it('should be able to programmatically select a falsy option', () => {
870877
fixture.destroy();
871878
TestBed.resetTestingModule();
@@ -1487,7 +1494,7 @@ class FormFieldChipList {
14871494
selector: 'basic-chip-list',
14881495
template: `
14891496
<mat-form-field>
1490-
<mat-chip-list placeholder="Food" [formControl]="control" [required]="isRequired"
1497+
<mat-chip-list placeholder="Food" [formControl]="control"
14911498
[tabIndex]="tabIndexOverride" [selectable]="selectable">
14921499
<mat-chip *ngFor="let food of foods" [value]="food.value" [disabled]="food.disabled">
14931500
{{ food.viewValue }}
@@ -1508,7 +1515,6 @@ class BasicChipList {
15081515
{value: 'sushi-7', viewValue: 'Sushi'},
15091516
];
15101517
control = new FormControl();
1511-
isRequired: boolean;
15121518
tabIndexOverride: number;
15131519
selectable: boolean;
15141520

src/material/chips/chip-list.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,13 @@ import {
2828
Self,
2929
ViewEncapsulation,
3030
} from '@angular/core';
31-
import {ControlValueAccessor, FormGroupDirective, NgControl, NgForm} from '@angular/forms';
31+
import {
32+
ControlValueAccessor,
33+
FormGroupDirective,
34+
NgControl,
35+
NgForm,
36+
Validators,
37+
} from '@angular/forms';
3238
import {
3339
CanUpdateErrorState,
3440
ErrorStateMatcher,
@@ -213,12 +219,14 @@ export class MatChipList extends _MatChipListBase implements MatFormFieldControl
213219
* @docs-private
214220
*/
215221
@Input()
216-
get required(): boolean { return this._required; }
222+
get required(): boolean {
223+
return this._required ?? this.ngControl?.control?.hasValidator(Validators.required) ?? false;
224+
}
217225
set required(value: boolean) {
218226
this._required = coerceBooleanProperty(value);
219227
this.stateChanges.next();
220228
}
221-
protected _required: boolean = false;
229+
protected _required: boolean | undefined;
222230

223231
/**
224232
* Implemented as part of MatFormFieldControl.

tools/public_api_guard/material/chips.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ export class MatChipList extends _MatChipListBase implements MatFormFieldControl
259259
get required(): boolean;
260260
set required(value: boolean);
261261
// (undocumented)
262-
protected _required: boolean;
262+
protected _required: boolean | undefined;
263263
get role(): string | null;
264264
get selectable(): boolean;
265265
set selectable(value: boolean);

0 commit comments

Comments
 (0)