import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; import { FormControl } from '@angular/forms'; import { Observable } from 'rxjs'; import { map, startWith } from 'rxjs/operators'; ​ export interface ItemData { item: string; selected: boolean; } @Component({ selector: 'multiselect-autocomplete', templateUrl: './multiselect-autocomplete.component.html', styleUrls: ['./multiselect-autocomplete.component.css'] }) /** * The MultiselectAutocompleteComponent mixes a angular material multiselect and a angular material autocomplete * it builds the base for many filter select option */ export class MultiselectAutocompleteComponent implements OnInit { @Output() result = new EventEmitter<{ key: string, data: Array }>(); @Input() placeholder: string = 'Select Data'; @Input() data: Array = []; @Input() key: string = ''; selectControl = new FormControl(); rawData: Array = []; selectData: Array = []; filteredData: Observable>; filterString: string = ''; /** * The constructor maps the default values */ constructor() { this.filteredData = this.selectControl.valueChanges.pipe( startWith(''), map(value => typeof value === 'string' ? value : this.filterString), map(filter => this.filter(filter)) ); } /** * The function ngOnInit imports the data (filter options) and maps it */ ngOnInit(): void { this.data.forEach((item: string) => { this.rawData.push({ item, selected: false }); }); var WebFont = require('webfontloader'); WebFont.load({ google: { families: [ 'Material Icons', ], }, }); } /** * The function filter filters the list with the select options * @param filter text to search for */ filter = (filter: string): Array => { this.filterString = filter; if (filter.length > 0) { return this.rawData.filter(option => { return option.item.toLowerCase().indexOf(filter.toLowerCase()) >= 0; }); } else { return this.rawData.slice(); } }; displayFn = (): string => ''; /** * The funtion optionClicked hanled the selection of a select option (filter option) * @param event selection event * @param data (filter)item data */ optionClicked = (event: Event, data: ItemData): void => { event.stopPropagation(); this.toggleSelection(data); }; /** * The function toggleSelection handles a click on a selection item * if it is already selected it will be removed from the selection, if it is not yet selected it will be selected * it builds the base for many filter select option */ toggleSelection = (data: ItemData): void => { data.selected = !data.selected; if (data.selected === true) { this.selectData.push(data); } else { const i = this.selectData.findIndex(value => value.item === data.item); this.selectData.splice(i, 1); } this.selectControl.setValue(this.selectData); this.emitAdjustedData(); }; /** * The emitAdjustedData emits the selected options the the parent component * its triggered when the selectbox is closed */ emitAdjustedData = (): void => { const results: Array = [] this.selectData.forEach((data: ItemData) => { results.push(data.item); }); this.result.emit({ key: this.key, data: results }); }; /** * The removeChip removes a option from the selection list if the user presses the remove button on the chip list */ removeChip = (data: ItemData): void => { this.toggleSelection(data); }; }