aboutsummaryrefslogtreecommitdiffstats
path: root/src/angular/autocomplete/autocomplete.component.ts
blob: 5570eff371432ef50c4eaf3d145c09b48f92b4f8 (plain)
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();
        }
    }
}