fix(chips): form field label pointing to non-existing elements (#9908)

Currently when a `mat-chip-list` is inside of a form field, the label of the form field has a `for` and `aria-owns` attributes that point to a non-existing element, because the `id` from the chip list isn't being used anywhere. These changes switch it to point to the chip list input, if it has any, otherwise it'll fall back to pointing to the chip list itself.
This commit is contained in:
Kristiyan Kostadinov
2018-03-09 10:28:08 -05:00
committed by Jeremy Elbourn
parent c42549ee29
commit 9337ae181f
4 changed files with 29 additions and 9 deletions
+4
View File
@@ -51,6 +51,10 @@ describe('MatChipInput', () => {
chipInputDirective._keydown(ENTER_EVENT);
expect(testChipInput.add).toHaveBeenCalled();
});
it('should have a default id', () => {
expect(inputNativeElement.getAttribute('id')).toBeTruthy();
});
});
describe('[addOnBlur]', () => {
+7
View File
@@ -21,6 +21,9 @@ export interface MatChipInputEvent {
value: string;
}
// Increasing integer for generating unique ids.
let nextUniqueId = 0;
/**
* Directive that adds chip-specific behaviors to an input element inside `<mat-form-field>`.
* May be placed inside or outside of an `<mat-chip-list>`.
@@ -34,6 +37,7 @@ export interface MatChipInputEvent {
'(blur)': '_blur()',
'(focus)': '_focus()',
'(input)': '_onInput()',
'[id]': 'id',
}
})
export class MatChipInput {
@@ -73,6 +77,9 @@ export class MatChipInput {
/** The input's placeholder text. */
@Input() placeholder: string = '';
/** Unique id for the input. */
@Input() id: string = `mat-chip-list-input-${nextUniqueId++}`;
/** Whether the input is empty. */
get empty(): boolean { return !this._inputElement.value; }
+13 -1
View File
@@ -377,6 +377,17 @@ describe('MatChipList', () => {
subscription.unsubscribe();
});
it('should point the label id to the chip input', () => {
const label = fixture.nativeElement.querySelector('label');
const input = fixture.nativeElement.querySelector('input');
fixture.detectChanges();
expect(label.getAttribute('for')).toBeTruthy();
expect(label.getAttribute('for')).toBe(input.getAttribute('id'));
expect(label.getAttribute('aria-owns')).toBe(input.getAttribute('id'));
});
});
describe('selection logic', () => {
@@ -1054,12 +1065,13 @@ class StandardChipList {
@Component({
template: `
<mat-form-field>
<mat-label>Add a chip</mat-label>
<mat-chip-list #chipList>
<mat-chip>Chip 1</mat-chip>
<mat-chip>Chip 1</mat-chip>
<mat-chip>Chip 1</mat-chip>
</mat-chip-list>
<input matInput name="test" [matChipInputFor]="chipList"/>
<input name="test" [matChipInputFor]="chipList"/>
</mat-form-field>
`
})
+5 -8
View File
@@ -87,7 +87,8 @@ export class MatChipListChange {
'class': 'mat-chip-list',
'(focus)': 'focus()',
'(blur)': '_blur()',
'(keydown)': '_keydown($event)'
'(keydown)': '_keydown($event)',
'[id]': '_uid',
},
providers: [{provide: MatFormFieldControl, useExisting: MatChipList}],
styleUrls: ['chips.css'],
@@ -130,7 +131,7 @@ export class MatChipList extends _MatChipListMixinBase implements MatFormFieldCo
protected _chipInput: MatChipInput;
/** Uid of the chip list */
protected _uid: string = `mat-chip-list-${nextUniqueId++}`;
_uid: string = `mat-chip-list-${nextUniqueId++}`;
/** The aria-describedby attribute on the chip list for improved a11y. */
_ariaDescribedby: string;
@@ -206,13 +207,9 @@ export class MatChipList extends _MatChipListMixinBase implements MatFormFieldCo
* Implemented as part of MatFormFieldControl.
* @docs-private
*/
@Input()
get id(): string { return this._id || this._uid; }
set id(value: string) {
this._id = value;
this.stateChanges.next();
get id(): string {
return this._chipInput ? this._chipInput.id : this._uid;
}
protected _id: string;
/**
* Implemented as part of MatFormFieldControl.