Skip to content

Commit 24ad356

Browse files
committed
docs(autocomplete): add autocomplete docs
1 parent fbed180 commit 24ad356

File tree

2 files changed

+150
-5
lines changed

2 files changed

+150
-5
lines changed

src/lib/autocomplete/OVERVIEW.md

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
2+
The autocomplete is a normal text input enhanced by a panel of suggested options. You can read more about
3+
autocompletes in the [Material Design spec](https://material.io/guidelines/components/text-fields.html#text-fields-auto-complete-text-field).
4+
5+
### Simple autocomplete
6+
7+
Start by adding a regular `mdInput` to the page. Let's assume you're using the `formControl` directive from the
8+
`@angular/forms` module to track the value of the input.
9+
10+
*my-comp.html*
11+
```html
12+
<md-input-container>
13+
<input type="text" mdInput [formControl]="myControl">
14+
</md-input-container>
15+
```
16+
17+
Next, create the autocomplete panel and the options displayed inside it. Each option should be defined by an
18+
`md-option` tag. Set each option's value property to whatever you'd like the value of the text input to be
19+
upon that option's selection.
20+
21+
*my-comp.html*
22+
```html
23+
<md-autocomplete>
24+
<md-option *ngFor="let option of options" [value]="option">
25+
{{ option }}
26+
</md-option>
27+
</md-autocomplete>
28+
```
29+
30+
Now we'll need to link the text input to its panel. We can do this by exporting the autocomplete panel instance into a
31+
local template variable (here we called it "auto"), and binding that variable to the input's `mdAutocomplete` property.
32+
33+
*my-comp.html*
34+
```html
35+
<md-input-container>
36+
<input type="text" mdInput [formControl]="myControl" [mdAutocomplete]="auto">
37+
</md-input-container>
38+
39+
<md-autocomplete #auto="mdAutocomplete">
40+
<md-option *ngFor="let option of options" [value]="option">
41+
{{ option }}
42+
</md-option>
43+
</md-autocomplete>
44+
```
45+
46+
### Adding a custom filter
47+
48+
At this point, the autocomplete panel should be toggleable on focus and options should be selectable. But if we want
49+
our options to filter when we type, we need to add a custom filter.
50+
51+
We already have access to the built-in `valueChanges` observable on the `FormControl`, so we can simply map the text
52+
input's values to the suggested options by passing them through our filter function. The resulting observable
53+
(`filteredOptions`) can be added to the template in place of the `options` property using the `async` pipe.
54+
55+
Below we are also priming our value change stream with `null` so that the options are filtered by that value on init
56+
(before there are any value changes).
57+
58+
*my-comp.ts*
59+
```ts
60+
class MyComp {
61+
myControl = new FormControl();
62+
options = [
63+
'One',
64+
'Two',
65+
'Three'
66+
];
67+
filteredOptions: Observable<string[]>;
68+
69+
ngOnInit() {
70+
this.filteredOptions = this.myControl.valueChanges
71+
.startWith(null)
72+
.map(val => val ? this.filter(val) : this.options.slice());
73+
}
74+
75+
filter(val: string): string[] {
76+
return this.options.filter(option => option.match(new RegExp(val, 'gi')));
77+
}
78+
}
79+
```
80+
81+
*my-comp.html*
82+
```html
83+
<md-input-container>
84+
<input type="text" mdInput [formControl]="myControl" [mdAutocomplete]="auto">
85+
</md-input-container>
86+
87+
<md-autocomplete #auto="mdAutocomplete">
88+
<md-option *ngFor="let option of filteredOptions | async" [value]="option">
89+
{{ option }}
90+
</md-option>
91+
</md-autocomplete>
92+
```
93+
94+
### Setting separate control and display values
95+
96+
If you want the option's control value (what is saved in the form) to be different than the option's display value
97+
(what is displayed in the actual text field), you'll need to set the `displayWith` property on your autocomplete
98+
element. A common use case for this might be if you want to save your data as an object, but display just one of
99+
the option's string properties.
100+
101+
To make this work, create a function on your component class that maps the control value to the desired display value.
102+
Then bind it to the autocomplete's `displayWith` property. You'll probably also want to add a step to your
103+
`valueChanges` stream that maps the value through your display function.
104+
105+
```html
106+
<md-input-container>
107+
<input type="text" mdInput [formControl]="myControl" [mdAutocomplete]="auto">
108+
</md-input-container>
109+
110+
<md-autocomplete #auto="mdAutocomplete" [displayWith]="displayFn">
111+
<md-option *ngFor="let option of filteredOptions | async" [value]="option">
112+
{{ option }}
113+
</md-option>
114+
</md-autocomplete>
115+
```
116+
117+
*my-comp.ts*
118+
```ts
119+
class MyComp {
120+
myControl = new FormControl();
121+
options = [
122+
{id: 1, name: 'One'},
123+
{id: 2, name: 'Two'},
124+
{id: 3, name: 'Three'}
125+
];
126+
filteredOptions: Observable<any[]>;
127+
128+
ngOnInit() {
129+
this.filteredOptions = this.myControl.valueChanges
130+
.startWith(null)
131+
.map(val => this.displayFn(val))
132+
.map(name => name ? this.filter(name) : this.options.slice());
133+
}
134+
135+
filter(val: string): any[] {
136+
return this.options.filter(option => option.match(new RegExp(val, 'gi')));
137+
}
138+
139+
displayFn(value: any): string {
140+
return value && typeof value === 'object' ? value.name : value;
141+
}
142+
}
143+
```
144+
145+
146+
#### Keyboard interaction:
147+
- <kbd>DOWN_ARROW</kbd>: Next option becomes active.
148+
- <kbd>UP_ARROW</kbd>: Previous option becomes active.
149+
- <kbd>ENTER</kbd>: Select currently active item.

src/lib/autocomplete/README.md

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1 @@
1-
2-
## Not yet implemented!
3-
4-
The autocomplete is not yet implemented. This is only a scaffold to make
5-
subsequent PRs easier to read. Please do not try to use yet :)
1+
See documentation on [material.angular.io](https://material.angular.io/).

0 commit comments

Comments
 (0)