Skip to content

Commit fa54e46

Browse files
Dinistrovalorkin
authored andcommitted
fix(typeahead): Added form support (#723)
1 parent 53c7fd1 commit fa54e46

File tree

3 files changed

+58
-38
lines changed

3 files changed

+58
-38
lines changed

components/typeahead/typeahead.directive.ts

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ import {
22
Directive, Input, Output, HostListener, EventEmitter, OnInit, ElementRef,
33
Renderer, DynamicComponentLoader, ComponentRef, ReflectiveInjector, provide, ViewContainerRef
44
} from '@angular/core';
5-
import {NgModel} from '@angular/forms';
5+
import {NgControl, FormControl} from '@angular/forms';
66
import {TypeaheadUtils} from './typeahead-utils';
77
import {TypeaheadContainerComponent} from './typeahead-container.component';
88
import {TypeaheadOptions} from './typeahead-options.class';
99

10-
import {Observable} from 'rxjs/Rx';
10+
import {Observable} from 'rxjs/Observable';
1111

1212
import 'rxjs/add/observable/from';
1313
import 'rxjs/add/operator/debounceTime';
@@ -21,13 +21,10 @@ import {global} from '@angular/core/src/facade/lang';
2121
const KeyboardEvent = (global as any).KeyboardEvent as KeyboardEvent;
2222
/* tslint:enable */
2323

24-
// https://github.com/angular/angular/blob/master/modules/@angular/src/core/forms/directives/shared.ts
25-
function setProperty(renderer:Renderer, elementRef:ElementRef, propName:string, propValue:any):void {
26-
renderer.setElementProperty(elementRef.nativeElement, propName, propValue);
27-
}
28-
2924
@Directive({
30-
selector: '[typeahead][ngModel]'
25+
/* tslint:disable */
26+
selector: '[typeahead][ngModel],[typeahead][formControlName]'
27+
/* tslint:enable */
3128
})
3229
export class TypeaheadDirective implements OnInit {
3330
@Output() public typeaheadLoading:EventEmitter<boolean> = new EventEmitter<boolean>(false);
@@ -62,7 +59,7 @@ export class TypeaheadDirective implements OnInit {
6259
private placement:string = 'bottom-left';
6360
private popup:Promise<ComponentRef<any>>;
6461

65-
private cd:NgModel;
62+
private ngControl:NgControl;
6663
private viewContainerRef:ViewContainerRef;
6764
private element:ElementRef;
6865
private renderer:Renderer;
@@ -142,10 +139,10 @@ export class TypeaheadDirective implements OnInit {
142139
}
143140
}
144141

145-
public constructor(cd:NgModel, viewContainerRef:ViewContainerRef, element:ElementRef,
142+
public constructor(control:NgControl, viewContainerRef:ViewContainerRef, element:ElementRef,
146143
renderer:Renderer, loader:DynamicComponentLoader) {
147144
this.element = element;
148-
this.cd = cd;
145+
this.ngControl = control;
149146
this.viewContainerRef = viewContainerRef;
150147
this.renderer = renderer;
151148
this.loader = loader;
@@ -176,8 +173,8 @@ export class TypeaheadDirective implements OnInit {
176173
let valueStr:string = ((typeof value === 'object' && this.typeaheadOptionField)
177174
? value[this.typeaheadOptionField]
178175
: value).toString();
179-
this.cd.viewToModelUpdate(valueStr);
180-
setProperty(this.renderer, this.element, 'value', valueStr);
176+
this.ngControl.viewToModelUpdate(valueStr);
177+
(this.ngControl.control as FormControl).updateValue(valueStr);
181178
this.hide();
182179
}
183180

@@ -204,8 +201,8 @@ export class TypeaheadDirective implements OnInit {
204201
this.container.parent = this;
205202
// This improves the speedas it won't have to be done for each list item
206203
let normalizedQuery = (this.typeaheadLatinize
207-
? TypeaheadUtils.latinize(this.cd.model)
208-
: this.cd.model).toString()
204+
? TypeaheadUtils.latinize(this.ngControl.control.value)
205+
: this.ngControl.control.value).toString()
209206
.toLowerCase();
210207
this.container.query = this.typeaheadSingleWords
211208
? TypeaheadUtils.tokenize(normalizedQuery, this.typeaheadWordDelimiters, this.typeaheadPhraseDelimiters)
@@ -325,8 +322,8 @@ export class TypeaheadDirective implements OnInit {
325322
if (this.container && this._matches.length > 0) {
326323
// This improves the speedas it won't have to be done for each list item
327324
let normalizedQuery = (this.typeaheadLatinize
328-
? TypeaheadUtils.latinize(this.cd.model)
329-
: this.cd.model).toString()
325+
? TypeaheadUtils.latinize(this.ngControl.control.value)
326+
: this.ngControl.control.value).toString()
330327
.toLowerCase();
331328
this.container.query = this.typeaheadSingleWords
332329
? TypeaheadUtils.tokenize(normalizedQuery, this.typeaheadWordDelimiters, this.typeaheadPhraseDelimiters)
Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,43 @@
11
<div class='container-fluid'>
2-
<h4>Static arrays</h4>
3-
<pre class="card card-block card-header">Model: {{selected | json}}</pre>
4-
<input [(ngModel)]="selected"
5-
[typeahead]="states"
6-
(typeaheadOnSelect)="typeaheadOnSelect($event)"
7-
class="form-control">
2+
<!-- Static arrays -->
3+
<h4>Static arrays</h4>
4+
<pre class="card card-block card-header">Model: {{selected | json}}</pre>
5+
<input [(ngModel)]="selected"
6+
[typeahead]="states"
7+
(typeaheadOnSelect)="typeaheadOnSelect($event)"
8+
class="form-control">
9+
10+
<!-- Asynchronous results -->
11+
<h4>Asynchronous results</h4>
12+
<pre class="card card-block card-header">Model: {{asyncSelected | json}}</pre>
13+
<input [(ngModel)]="asyncSelected"
14+
[typeahead]="dataSource"
15+
(typeaheadLoading)="changeTypeaheadLoading($event)"
16+
(typeaheadNoResults)="changeTypeaheadNoResults($event)"
17+
(typeaheadOnSelect)="typeaheadOnSelect($event)"
18+
[typeaheadOptionsLimit]="7"
19+
[typeaheadOptionField]="'name'"
20+
placeholder="Locations loaded with timeout"
21+
class="form-control">
22+
<div *ngIf="typeaheadLoading===true">
23+
<i class="glyphicon glyphicon-refresh ng-hide" style=""></i>
24+
</div>
25+
<div *ngIf="typeaheadNoResults===true" class="" style="">
26+
<i class="glyphicon glyphicon-remove"></i> No Results Found
27+
</div>
828

9-
<h4>Asynchronous results</h4>
10-
<pre class="card card-block card-header">Model: {{asyncSelected | json}}</pre>
11-
<input [(ngModel)]="asyncSelected"
12-
[typeahead]="dataSource"
13-
(typeaheadLoading)="changeTypeaheadLoading($event)"
14-
(typeaheadNoResults)="changeTypeaheadNoResults($event)"
29+
<!--Typeahead inside a form-->
30+
<h4>Typeahead inside a form</h4>
31+
<pre class="card card-block card-header">Model: {{myForm.value.state | json}}</pre>
32+
<form [formGroup]="myForm">
33+
<input formControlName="state"
34+
[typeahead]="states"
1535
(typeaheadOnSelect)="typeaheadOnSelect($event)"
1636
[typeaheadOptionsLimit]="7"
1737
[typeaheadOptionField]="'name'"
18-
placeholder="Locations loaded with timeout"
38+
placeholder="Typeahead inside a form"
1939
class="form-control">
20-
<div *ngIf="typeaheadLoading===true">
21-
<i class="glyphicon glyphicon-refresh ng-hide" style=""></i>
22-
</div>
23-
<div *ngIf="typeaheadNoResults===true" class="" style="">
24-
<i class="glyphicon glyphicon-remove"></i> No Results Found
25-
</div>
40+
</form>
41+
42+
2643
</div>

demo/components/typeahead/typeahead-demo.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {Component} from '@angular/core';
22
import {CORE_DIRECTIVES} from '@angular/common';
3-
import {FORM_DIRECTIVES} from '@angular/forms';
3+
import {FORM_DIRECTIVES, REACTIVE_FORM_DIRECTIVES, FormGroup, FormControl} from '@angular/forms';
44
import {Observable} from 'rxjs/Observable';
55

66
import {TYPEAHEAD_DIRECTIVES} from '../../../ng2-bootstrap';
@@ -10,10 +10,16 @@ let template = require('./typeahead-demo.html');
1010

1111
@Component({
1212
selector: 'typeahead-demo',
13-
directives: [TYPEAHEAD_DIRECTIVES, CORE_DIRECTIVES, FORM_DIRECTIVES],
13+
directives: [TYPEAHEAD_DIRECTIVES, CORE_DIRECTIVES, FORM_DIRECTIVES, REACTIVE_FORM_DIRECTIVES],
1414
template: template
1515
})
1616
export class TypeaheadDemoComponent {
17+
public stateCtrl:FormControl = new FormControl();
18+
19+
public myForm:FormGroup= new FormGroup({
20+
state: this.stateCtrl
21+
});
22+
1723
public selected:string = '';
1824
public dataSource:Observable<any>;
1925
public asyncSelected:string = '';

0 commit comments

Comments
 (0)