2019-07-15 17:49:30 +02:00
|
|
|
|
import { Component, Input, ViewChild, OnDestroy, ChangeDetectionStrategy } from '@angular/core';
|
2019-05-14 16:59:47 +02:00
|
|
|
|
import { FormControl } from '@angular/forms';
|
|
|
|
|
import { MatSelect } from '@angular/material';
|
2019-01-31 11:15:21 +01:00
|
|
|
|
|
2019-05-14 16:59:47 +02:00
|
|
|
|
import { BehaviorSubject, Subscription } from 'rxjs';
|
|
|
|
|
import { auditTime } from 'rxjs/operators';
|
2018-09-13 09:23:57 +02:00
|
|
|
|
import { TranslateService } from '@ngx-translate/core';
|
2019-01-31 11:15:21 +01:00
|
|
|
|
|
2018-10-15 11:52:57 +02:00
|
|
|
|
import { Selectable } from '../selectable';
|
2018-09-13 07:57:38 +02:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Reusable Searchable Value Selector
|
|
|
|
|
*
|
2019-06-28 07:24:28 +02:00
|
|
|
|
* Use `multiple="true"`, `[InputListValues]=myValues`,`[formControl]="myformcontrol"` and `placeholder={{listname}}` to pass the Values and Listname
|
2018-09-13 07:57:38 +02:00
|
|
|
|
*
|
|
|
|
|
* ## Examples:
|
|
|
|
|
*
|
|
|
|
|
* ### Usage of the selector:
|
|
|
|
|
*
|
|
|
|
|
* ngDefaultControl: https://stackoverflow.com/a/39053470
|
|
|
|
|
*
|
|
|
|
|
* ```html
|
|
|
|
|
* <os-search-value-selector
|
|
|
|
|
* ngDefaultControl
|
2018-09-19 15:18:57 +02:00
|
|
|
|
* [multiple]="true"
|
2018-09-13 07:57:38 +02:00
|
|
|
|
* placeholder="Placeholder"
|
2018-11-22 12:33:40 +01:00
|
|
|
|
* [InputListValues]="myListValues"
|
2018-09-13 07:57:38 +02:00
|
|
|
|
* [formControl]="myformcontrol">
|
|
|
|
|
* </os-search-value-selector>
|
|
|
|
|
* ```
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
@Component({
|
|
|
|
|
selector: 'os-search-value-selector',
|
|
|
|
|
templateUrl: './search-value-selector.component.html',
|
2019-07-15 17:49:30 +02:00
|
|
|
|
styleUrls: ['./search-value-selector.component.scss'],
|
|
|
|
|
changeDetection: ChangeDetectionStrategy.OnPush
|
2018-09-13 07:57:38 +02:00
|
|
|
|
})
|
2019-05-14 16:59:47 +02:00
|
|
|
|
export class SearchValueSelectorComponent implements OnDestroy {
|
2018-09-13 07:57:38 +02:00
|
|
|
|
/**
|
2019-05-14 16:59:47 +02:00
|
|
|
|
* Saves the current subscription to _inputListSubject.
|
2018-09-13 07:57:38 +02:00
|
|
|
|
*/
|
2019-05-14 16:59:47 +02:00
|
|
|
|
private _inputListSubscription: Subscription = null;
|
2018-09-13 07:57:38 +02:00
|
|
|
|
|
2018-11-08 11:33:30 +01:00
|
|
|
|
/**
|
2019-05-14 16:59:47 +02:00
|
|
|
|
* Value of the search input
|
2018-11-08 11:33:30 +01:00
|
|
|
|
*/
|
2019-05-14 16:59:47 +02:00
|
|
|
|
private searchValue = '';
|
2018-11-08 11:33:30 +01:00
|
|
|
|
|
|
|
|
|
/**
|
2019-05-14 16:59:47 +02:00
|
|
|
|
* All items
|
2018-11-08 11:33:30 +01:00
|
|
|
|
*/
|
2019-05-14 16:59:47 +02:00
|
|
|
|
private selectableItems: Selectable[];
|
2018-11-08 11:33:30 +01:00
|
|
|
|
|
2018-09-13 07:57:38 +02:00
|
|
|
|
/**
|
|
|
|
|
* Decide if this should be a single or multi-select-field
|
|
|
|
|
*/
|
|
|
|
|
@Input()
|
2019-05-14 16:59:47 +02:00
|
|
|
|
public multiple = false;
|
2018-09-13 07:57:38 +02:00
|
|
|
|
|
2018-11-22 12:33:40 +01:00
|
|
|
|
/**
|
|
|
|
|
* Decide, if none should be included, if multiple is false.
|
|
|
|
|
*/
|
|
|
|
|
@Input()
|
|
|
|
|
public includeNone = false;
|
|
|
|
|
|
2019-06-28 07:24:28 +02:00
|
|
|
|
@Input()
|
|
|
|
|
public noneTitle = '–';
|
|
|
|
|
|
2019-07-04 14:37:36 +02:00
|
|
|
|
/**
|
|
|
|
|
* Boolean, whether the component should be rendered with full width.
|
|
|
|
|
*/
|
|
|
|
|
@Input()
|
|
|
|
|
public fullWidth = false;
|
|
|
|
|
|
2018-09-13 07:57:38 +02:00
|
|
|
|
/**
|
2018-11-08 11:33:30 +01:00
|
|
|
|
* The inputlist subject. Subscribes to it and updates the selector, if the subject
|
|
|
|
|
* changes its values.
|
2018-09-13 07:57:38 +02:00
|
|
|
|
*/
|
|
|
|
|
@Input()
|
2018-11-08 11:33:30 +01:00
|
|
|
|
public set InputListValues(value: BehaviorSubject<Selectable[]>) {
|
2019-07-04 14:37:36 +02:00
|
|
|
|
if (!value) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2018-11-08 11:33:30 +01:00
|
|
|
|
// unsubscribe to old subscription.
|
|
|
|
|
if (this._inputListSubscription) {
|
|
|
|
|
this._inputListSubscription.unsubscribe();
|
|
|
|
|
}
|
2019-05-14 16:59:47 +02:00
|
|
|
|
// 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 });
|
|
|
|
|
}
|
2018-11-08 11:33:30 +01:00
|
|
|
|
});
|
|
|
|
|
}
|
2018-09-13 07:57:38 +02:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Placeholder of the List
|
|
|
|
|
*/
|
|
|
|
|
@Input()
|
|
|
|
|
public listname: String;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Name of the Form
|
|
|
|
|
*/
|
|
|
|
|
@Input()
|
|
|
|
|
public formControl: FormControl;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The MultiSelect Component
|
|
|
|
|
*/
|
2019-07-01 11:23:33 +02:00
|
|
|
|
@ViewChild('thisSelector', { static: true })
|
2018-09-13 07:57:38 +02:00
|
|
|
|
public thisSelector: MatSelect;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Empty constructor
|
|
|
|
|
*/
|
2019-03-11 09:48:20 +01:00
|
|
|
|
public constructor(protected translate: TranslateService) {}
|
2018-09-13 07:57:38 +02:00
|
|
|
|
|
2018-11-08 11:33:30 +01:00
|
|
|
|
/**
|
|
|
|
|
* Unsubscribe on destroing.
|
|
|
|
|
*/
|
|
|
|
|
public ngOnDestroy(): void {
|
|
|
|
|
if (this._inputListSubscription) {
|
|
|
|
|
this._inputListSubscription.unsubscribe();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-13 07:57:38 +02:00
|
|
|
|
/**
|
2019-05-14 16:59:47 +02:00
|
|
|
|
* Function to get a list filtered by the entered search value.
|
|
|
|
|
*
|
|
|
|
|
* @returns The filtered list of items.
|
2018-09-13 07:57:38 +02:00
|
|
|
|
*/
|
2019-05-14 16:59:47 +02:00
|
|
|
|
public getFilteredItems(): Selectable[] {
|
|
|
|
|
if (this.selectableItems) {
|
2019-07-08 18:09:03 +02:00
|
|
|
|
return this.selectableItems.filter(item => {
|
|
|
|
|
const idString = '' + item.id;
|
|
|
|
|
const foundId =
|
|
|
|
|
idString
|
|
|
|
|
.trim()
|
|
|
|
|
.toLowerCase()
|
|
|
|
|
.indexOf(this.searchValue) !== -1;
|
|
|
|
|
|
|
|
|
|
if (foundId) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (
|
2019-05-14 16:59:47 +02:00
|
|
|
|
item
|
2018-09-13 07:57:38 +02:00
|
|
|
|
.toString()
|
|
|
|
|
.toLowerCase()
|
2019-05-14 16:59:47 +02:00
|
|
|
|
.indexOf(this.searchValue) > -1
|
2019-07-08 18:09:03 +02:00
|
|
|
|
);
|
|
|
|
|
});
|
2019-05-14 16:59:47 +02:00
|
|
|
|
}
|
2018-09-13 07:57:38 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2019-05-14 16:59:47 +02:00
|
|
|
|
* Function to set the search value.
|
|
|
|
|
*
|
|
|
|
|
* @param searchValue the new value the user is searching for.
|
2018-09-13 07:57:38 +02:00
|
|
|
|
*/
|
2019-05-14 16:59:47 +02:00
|
|
|
|
public onSearch(searchValue: string): void {
|
|
|
|
|
this.searchValue = searchValue.toLowerCase();
|
2018-09-13 07:57:38 +02:00
|
|
|
|
}
|
|
|
|
|
}
|