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