1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
import { OnInit, animate, Component, EventEmitter, Input, Output, state, style, transition, trigger } from '@angular/core';
import { FilterBarComponent } from "../filterbar/filter-bar.component";
import { URLSearchParams, Http } from "@angular/http";
import { AutocompletePipe } from "./autocomplete.pipe";
import template from "./autocomplete.component.html";
import 'rxjs/add/operator/map';
export interface IDataSchema {
key: string;
value: string;
}
@Component({
selector: 'sdc-autocomplete',
template: template,
animations: [
trigger('displayResultsAnimation', [
state('true', style({
height: '*',
opacity: 1
})),
state('false', style({
height: 0,
opacity: 0
})),
transition('* => *', animate('200ms'))
]),
],
providers: [AutocompletePipe]
})
export class SearchWithAutoCompleteComponent implements OnInit {
@Input() public data: any[] = [];
@Input() public dataSchema: IDataSchema;
@Input() public dataUrl: string;
@Input() public label: string;
@Input() public placeholder: string;
@Output() public itemSelected: EventEmitter<any> = new EventEmitter<any>();
private searchQuery: string;
private complexData: any[] = [];
private autoCompleteResults: any[] = [];
private isItemSelected: boolean = false;
public constructor(private http: Http, private autocompletePipe: AutocompletePipe) {
}
public ngOnInit(): void {
if (this.data) {
this.handleLocalData();
}
this.searchQuery = "";
}
private handleLocalData = (): void => {
// Convert the data (simple | complex) to unified complex data with key value.
// In case user supplied dataSchema, this is complex data
if (!this.dataSchema) {
this.convertSimpleData();
} else {
this.convertComplexData();
}
}
private convertSimpleData = (): void => {
this.complexData = [];
this.data.forEach((item: any) => {
this.complexData.push({key: item, value: item});
});
}
private convertComplexData = (): void => {
this.complexData = [];
this.data.forEach((item: any) => {
this.complexData.push({key: item[this.dataSchema.key], value: item[this.dataSchema.value]});
});
}
private onItemSelected = (selectedItem: IDataSchema): void => {
this.searchQuery = selectedItem.value;
this.isItemSelected = true;
this.autoCompleteResults = [];
this.itemSelected.emit(selectedItem.key);
}
private onSearchQueryChanged = (searchText: string): void => {
if (searchText !== this.searchQuery) {
this.searchQuery = searchText;
if (!this.searchQuery) {
this.onClearSearch();
} else {
if (this.dataUrl) {
const params: URLSearchParams = new URLSearchParams();
params.set('searchQuery', this.searchQuery);
this.http.get(this.dataUrl, {search: params})
.map((response) => {
this.data = response.json();
this.handleLocalData();
this.autoCompleteResults = this.complexData;
}).subscribe();
} else {
this.autoCompleteResults = this.autocompletePipe.transform(this.complexData, this.searchQuery);
}
}
this.isItemSelected = false;
}
}
private onClearSearch = (): void => {
this.autoCompleteResults = [];
if (this.isItemSelected) {
this.itemSelected.emit();
}
}
}
|