129 lines
3.6 KiB
TypeScript
129 lines
3.6 KiB
TypeScript
|
||
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<string> }>();
|
||
@Input() placeholder: string = 'Select Data';
|
||
@Input() data: Array<string> = [];
|
||
@Input() key: string = '';
|
||
selectControl = new FormControl();
|
||
|
||
rawData: Array<ItemData> = [];
|
||
selectData: Array<ItemData> = [];
|
||
filteredData: Observable<Array<ItemData>>;
|
||
filterString: string = '';
|
||
|
||
/**
|
||
* The constructor maps the default values
|
||
*/
|
||
constructor() {
|
||
this.filteredData = this.selectControl.valueChanges.pipe(
|
||
startWith<string>(''),
|
||
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<ItemData> => {
|
||
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<string> = []
|
||
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);
|
||
};
|
||
|
||
}
|