ChangeCalendar/frontend/src/app/multiselect-autocomplete/multiselect-autocomplete.co...

209 lines
5.9 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { FormControl } from '@angular/forms';
import { Observable } from 'rxjs';
import { map, startWith } from 'rxjs/operators';
import { MatChipsModule } from '@angular/material/chips'; // Importiere MatChipsModule
import * as WebFont from 'webfontloader'; // Verwende import * as
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 = '';
@Input() appliedFilters: Array<string> = [];
selectControl = new FormControl();
rawData: Array<ItemData> = [];
selectData: Array<ItemData> = [];
filteredData: Observable<Array<ItemData>>;
filterString: string = '';
showCheckbox: boolean = true;
allSelected: boolean = false;
indeterminate: boolean = false;
/**
* 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 });
});
WebFont.load({
google: {
families: [
'Material Icons',
],
},
});
//console.log(this.appliedFilters);
//console.log(this.rawData);
if(this.appliedFilters.length > 0){
for (const filter of this.appliedFilters) {
for (const item of this.rawData) {
if(item.item == filter){
//console.log("MATCH"+item.item);
item.selected = true;
this.toggleSelection({'item': filter, selected: false});
}
}
}
}
//console.log(this.selectData);
this.evaluateIndeterminate();
}
/**
* 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 => {
////console.log(data);
//console.log(this.selectData);
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();
this.evaluateIndeterminate();
};
/**
* 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 => {
let dat = {item: data.item, selected: true};
this.toggleSelection(dat);
for (const rawItem of this.rawData) {
if(data.item == rawItem.item){
rawItem.selected = false;
}
}
};
public toggleAll(): void {
this.allSelected = !this.allSelected;
if (this.allSelected) {
for (const item of this.rawData) {
const filterExists = this.selectData.some(selectedItem => selectedItem.item === item.item);
if (!filterExists) {
item.selected = true;
this.selectData.push(item);
}
}
} else {
for (const item of this.rawData) {
const index = this.selectData.findIndex(selectedItem => selectedItem.item === item.item);
if (index !== -1) {
item.selected = false;
this.selectData.splice(index, 1);
}
}
}
this.selectControl.setValue(this.selectData);
this.emitAdjustedData();
this.evaluateIndeterminate();
}
public showCheckBox(): void{
this.showCheckbox = true;
//console.log("####")
}
public hideCheckBox(): void{
this.showCheckbox = false;
}
public evaluateIndeterminate():void{
if(this.selectData.length == 0){
this.indeterminate = false;
this.allSelected = false;
}
if(this.selectData.length > 0 && this.selectData.length<this.rawData.length){
this.indeterminate = true;
}
if(this.selectData.length == this.rawData.length){
this.indeterminate = false;
this.allSelected = true;
}
}
}