From 9ca2a0a1df8487eeb4f510d15879d601929a09dd Mon Sep 17 00:00:00 2001 From: HermanWKeuris Date: Wed, 24 Jul 2024 11:08:26 +0200 Subject: [PATCH] docs(material/chips): describe how to use chips in forms #22906 (#29405) * docs(material/chips): describe how to use chips in forms Added a description and examples in the docs of how to use chips in both reactive and template-driven forms. Fixes #22906 * docs(material/chips): describe how to use chips in forms Updated indentation --- .../chips-reactive-form-example.css | 3 + .../chips-reactive-form-example.html | 21 +++++++ .../chips-reactive-form-example.ts | 57 +++++++++++++++++++ .../chips-template-form-example.css | 3 + .../chips-template-form-example.html | 21 +++++++ .../chips-template-form-example.ts | 50 ++++++++++++++++ .../material/chips/index.ts | 2 + src/material/chips/chips.md | 7 +++ 8 files changed, 164 insertions(+) create mode 100644 src/components-examples/material/chips/chips-reactive-form/chips-reactive-form-example.css create mode 100644 src/components-examples/material/chips/chips-reactive-form/chips-reactive-form-example.html create mode 100644 src/components-examples/material/chips/chips-reactive-form/chips-reactive-form-example.ts create mode 100644 src/components-examples/material/chips/chips-template-form/chips-template-form-example.css create mode 100644 src/components-examples/material/chips/chips-template-form/chips-template-form-example.html create mode 100644 src/components-examples/material/chips/chips-template-form/chips-template-form-example.ts diff --git a/src/components-examples/material/chips/chips-reactive-form/chips-reactive-form-example.css b/src/components-examples/material/chips/chips-reactive-form/chips-reactive-form-example.css new file mode 100644 index 000000000000..e3b9d8ab676c --- /dev/null +++ b/src/components-examples/material/chips/chips-reactive-form/chips-reactive-form-example.css @@ -0,0 +1,3 @@ +.example-form-field { + width: 100%; +} diff --git a/src/components-examples/material/chips/chips-reactive-form/chips-reactive-form-example.html b/src/components-examples/material/chips/chips-reactive-form/chips-reactive-form-example.html new file mode 100644 index 000000000000..6e809960bfc5 --- /dev/null +++ b/src/components-examples/material/chips/chips-reactive-form/chips-reactive-form-example.html @@ -0,0 +1,21 @@ +
+

Chips inside of a Reactive form

+ + Video keywords + + @for (keyword of reactiveKeywords(); track keyword) { + + {{keyword}} + + + } + + + +
\ No newline at end of file diff --git a/src/components-examples/material/chips/chips-reactive-form/chips-reactive-form-example.ts b/src/components-examples/material/chips/chips-reactive-form/chips-reactive-form-example.ts new file mode 100644 index 000000000000..34b95a5d5846 --- /dev/null +++ b/src/components-examples/material/chips/chips-reactive-form/chips-reactive-form-example.ts @@ -0,0 +1,57 @@ +import {LiveAnnouncer} from '@angular/cdk/a11y'; +import {ChangeDetectionStrategy, Component, inject, signal} from '@angular/core'; +import {FormControl, ReactiveFormsModule} from '@angular/forms'; +import {MatButtonModule} from '@angular/material/button'; +import {MatChipInputEvent, MatChipsModule} from '@angular/material/chips'; +import {MatFormFieldModule} from '@angular/material/form-field'; +import {MatIconModule} from '@angular/material/icon'; + +/** + * @title Chips in reactive forms + */ +@Component({ + selector: 'chips-reactive-form-example', + templateUrl: 'chips-reactive-form-example.html', + styleUrl: 'chips-reactive-form-example.css', + standalone: true, + imports: [ + MatButtonModule, + MatFormFieldModule, + MatChipsModule, + ReactiveFormsModule, + MatIconModule, + ], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class ChipsReactiveFormExample { + readonly reactiveKeywords = signal(['angular', 'how-to', 'tutorial', 'accessibility']); + readonly formControl = new FormControl(['angular']); + + announcer = inject(LiveAnnouncer); + + removeReactiveKeyword(keyword: string) { + this.reactiveKeywords.update(keywords => { + const index = keywords.indexOf(keyword); + if (index < 0) { + return keywords; + } + + keywords.splice(index, 1); + this.announcer.announce(`removed ${keyword} from reactive form`); + return [...keywords]; + }); + } + + addReactiveKeyword(event: MatChipInputEvent): void { + const value = (event.value || '').trim(); + + // Add our keyword + if (value) { + this.reactiveKeywords.update(keywords => [...keywords, value]); + this.announcer.announce(`added ${value} to reactive form`); + } + + // Clear the input value + event.chipInput!.clear(); + } +} diff --git a/src/components-examples/material/chips/chips-template-form/chips-template-form-example.css b/src/components-examples/material/chips/chips-template-form/chips-template-form-example.css new file mode 100644 index 000000000000..e3b9d8ab676c --- /dev/null +++ b/src/components-examples/material/chips/chips-template-form/chips-template-form-example.css @@ -0,0 +1,3 @@ +.example-form-field { + width: 100%; +} diff --git a/src/components-examples/material/chips/chips-template-form/chips-template-form-example.html b/src/components-examples/material/chips/chips-template-form/chips-template-form-example.html new file mode 100644 index 000000000000..e9a99a6667a3 --- /dev/null +++ b/src/components-examples/material/chips/chips-template-form/chips-template-form-example.html @@ -0,0 +1,21 @@ +
+

Chips inside of a Template-driven form

+ + Video keywords + + @for (keyword of templateKeywords(); track keyword) { + + {{keyword}} + + + } + + + +
diff --git a/src/components-examples/material/chips/chips-template-form/chips-template-form-example.ts b/src/components-examples/material/chips/chips-template-form/chips-template-form-example.ts new file mode 100644 index 000000000000..d35791b68dca --- /dev/null +++ b/src/components-examples/material/chips/chips-template-form/chips-template-form-example.ts @@ -0,0 +1,50 @@ +import {LiveAnnouncer} from '@angular/cdk/a11y'; +import {ChangeDetectionStrategy, Component, inject, signal} from '@angular/core'; +import {FormsModule} from '@angular/forms'; +import {MatButtonModule} from '@angular/material/button'; +import {MatChipInputEvent, MatChipsModule} from '@angular/material/chips'; +import {MatFormFieldModule} from '@angular/material/form-field'; +import {MatIconModule} from '@angular/material/icon'; + +/** + * @title Chips in template-driven forms + */ +@Component({ + selector: 'chips-template-form-example', + templateUrl: 'chips-template-form-example.html', + styleUrl: 'chips-template-form-example.css', + standalone: true, + imports: [MatButtonModule, MatFormFieldModule, MatChipsModule, FormsModule, MatIconModule], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class ChipsTemplateFormExample { + readonly templateKeywords = signal(['angular', 'how-to', 'tutorial', 'accessibility']); + + announcer = inject(LiveAnnouncer); + + removeTemplateKeyword(keyword: string) { + this.templateKeywords.update(keywords => { + const index = keywords.indexOf(keyword); + if (index < 0) { + return keywords; + } + + keywords.splice(index, 1); + this.announcer.announce(`removed ${keyword} from template form`); + return [...keywords]; + }); + } + + addTemplateKeyword(event: MatChipInputEvent): void { + const value = (event.value || '').trim(); + + // Add our keyword + if (value) { + this.templateKeywords.update(keywords => [...keywords, value]); + this.announcer.announce(`added ${value} to template form`); + } + + // Clear the input value + event.chipInput!.clear(); + } +} diff --git a/src/components-examples/material/chips/index.ts b/src/components-examples/material/chips/index.ts index 4d2488b23e9c..66c923e7616c 100644 --- a/src/components-examples/material/chips/index.ts +++ b/src/components-examples/material/chips/index.ts @@ -5,4 +5,6 @@ export {ChipsOverviewExample} from './chips-overview/chips-overview-example'; export {ChipsStackedExample} from './chips-stacked/chips-stacked-example'; export {ChipsHarnessExample} from './chips-harness/chips-harness-example'; export {ChipsFormControlExample} from './chips-form-control/chips-form-control-example'; +export {ChipsReactiveFormExample} from './chips-reactive-form/chips-reactive-form-example'; +export {ChipsTemplateFormExample} from './chips-template-form/chips-template-form-example'; export {ChipsAvatarExample} from './chips-avatar/chips-avatar-example'; diff --git a/src/material/chips/chips.md b/src/material/chips/chips.md index c4869f0f4dd1..235e76453559 100644 --- a/src/material/chips/chips.md +++ b/src/material/chips/chips.md @@ -40,6 +40,13 @@ Chips are always used inside a container. To create chips connected to an input +### Use with `@angular/forms` +Chips are compatible with `@angular/forms` and supports both `FormsModule` +and `ReactiveFormsModule`. + + + + #### Disabled `` Use the `disabled` Input to disable a ``. This gives the `` a disabled appearance and prevents the user from interacting with it.