OpenSlides/client/src/app/shared/components/search-value-selector/search-value-selector.component.ts
2019-07-30 09:53:14 +02:00

171 lines
4.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { ChangeDetectionStrategy, Component, Input, OnDestroy, ViewChild } from '@angular/core';
import { FormControl } from '@angular/forms';
import { MatSelect } from '@angular/material';
import { TranslateService } from '@ngx-translate/core';
import { BehaviorSubject, Subscription } from 'rxjs';
import { auditTime } from 'rxjs/operators';
import { Selectable } from '../selectable';
/**
* Reusable Searchable Value Selector
*
* Use `multiple="true"`, `[InputListValues]=myValues`,`[formControl]="myformcontrol"` and `placeholder={{listname}}` to pass the Values and Listname
*
* ## Examples:
*
* ### Usage of the selector:
*
* ngDefaultControl: https://stackoverflow.com/a/39053470
*
* ```html
* <os-search-value-selector
* ngDefaultControl
* [multiple]="true"
* placeholder="Placeholder"
* [InputListValues]="myListValues"
* [formControl]="myformcontrol">
* </os-search-value-selector>
* ```
*
*/
@Component({
selector: 'os-search-value-selector',
templateUrl: './search-value-selector.component.html',
styleUrls: ['./search-value-selector.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class SearchValueSelectorComponent implements OnDestroy {
/**
* Saves the current subscription to _inputListSubject.
*/
private _inputListSubscription: Subscription = null;
/**
* Value of the search input
*/
private searchValue = '';
/**
* All items
*/
private selectableItems: Selectable[];
/**
* Decide if this should be a single or multi-select-field
*/
@Input()
public multiple = false;
/**
* Decide, if none should be included, if multiple is false.
*/
@Input()
public includeNone = false;
@Input()
public noneTitle = '';
/**
* Boolean, whether the component should be rendered with full width.
*/
@Input()
public fullWidth = false;
/**
* The inputlist subject. Subscribes to it and updates the selector, if the subject
* changes its values.
*/
@Input()
public set InputListValues(value: BehaviorSubject<Selectable[]>) {
if (!value) {
return;
}
// unsubscribe to old subscription.
if (this._inputListSubscription) {
this._inputListSubscription.unsubscribe();
}
// this.inputSubject = value;
this._inputListSubscription = value.pipe(auditTime(10)).subscribe(items => {
this.selectableItems = items;
if (this.formControl) {
items.length === 0
? this.formControl.disable({ emitEvent: false })
: this.formControl.enable({ emitEvent: false });
}
});
}
/**
* Placeholder of the List
*/
@Input()
public listname: String;
/**
* Name of the Form
*/
@Input()
public formControl: FormControl;
/**
* The MultiSelect Component
*/
@ViewChild('thisSelector', { static: true })
public thisSelector: MatSelect;
/**
* Empty constructor
*/
public constructor(protected translate: TranslateService) {}
/**
* Unsubscribe on destroing.
*/
public ngOnDestroy(): void {
if (this._inputListSubscription) {
this._inputListSubscription.unsubscribe();
}
}
/**
* Function to get a list filtered by the entered search value.
*
* @returns The filtered list of items.
*/
public getFilteredItems(): Selectable[] {
if (this.selectableItems) {
return this.selectableItems.filter(item => {
const idString = '' + item.id;
const foundId =
idString
.trim()
.toLowerCase()
.indexOf(this.searchValue) !== -1;
if (foundId) {
return true;
}
return (
item
.toString()
.toLowerCase()
.indexOf(this.searchValue) > -1
);
});
}
}
/**
* Function to set the search value.
*
* @param searchValue the new value the user is searching for.
*/
public onSearch(searchValue: string): void {
this.searchValue = searchValue.toLowerCase();
}
}