nm-select-combo
src/app/shared/widgets/select-combo/select-combo.component.ts
changeDetection | ChangeDetectionStrategy.OnPush |
selector | nm-select-combo |
templateUrl | ./select-combo.component.html |
Widget inputs |
Widget outputs |
Properties |
|
Methods |
|
constructor(_widgetframeService: WidgetframeService, _currentLocaleService: CurrentLocaleService, cdr: ChangeDetectorRef, localstorageService: LocalStorageService)
|
|||||||||||||||
Parameters :
|
Public configureWidget | ||||||
configureWidget(configuration: WidgetConfig
|
||||||
Decorators : WidgetConfigure
|
||||||
Parameters :
Returns :
void
|
isAllSelected | ||||
isAllSelected(allSelected: )
|
||||
Parameters :
Returns :
void
|
Public onChange | ||||||
onChange(value: any)
|
||||||
Parameters :
Returns :
void
|
Private setPreselectValues |
setPreselectValues()
|
Returns :
void
|
Private setValidSelectedValues | |||||||||
setValidSelectedValues(values: string[], options: any[])
|
|||||||||
Parameters :
Returns :
void
|
Public _allLocalstorageEntry |
_allLocalstorageEntry:
|
Type : LocalStorageEntry
|
Public _optionsDataKey |
_optionsDataKey:
|
Type : string
|
Public _optionsDataUrl |
_optionsDataUrl:
|
Type : string
|
Public _preselectedValues |
_preselectedValues:
|
Type : string[]
|
Public _selectionLocalstorageEntry |
_selectionLocalstorageEntry:
|
Type : LocalStorageEntry
|
Public _unsubscribe |
_unsubscribe:
|
Default value : NgUnsubscribe.create()
|
Public allowEmpty |
allowEmpty:
|
Type : boolean
|
Public allSelected |
allSelected:
|
Default value : new ReplaySubject<boolean>(1)
|
Decorators : WidgetOutput
|
Public clearable |
clearable:
|
Type : boolean
|
Public combo |
combo:
|
Type : NmComboComponent
|
Decorators : ViewChild
|
Public configuration |
configuration:
|
Type : WidgetConfig<SelectComboConfiguration>
|
Decorators : WidgetConfiguration
|
Public customClass |
customClass:
|
Type : string
|
Public disabled |
disabled:
|
Type : boolean
|
Public displayKey |
displayKey:
|
Type : string
|
Public filterPlaceholder |
filterPlaceholder:
|
Type : string
|
Public groupKey |
groupKey:
|
Type : string
|
Public groupStrategy |
groupStrategy:
|
Type : GroupByStrategy
|
Public hide |
hide:
|
Type : boolean
|
Default value : false
|
Public hideChannel |
hideChannel:
|
Default value : new Subject<boolean>()
|
Decorators : WidgetInput
|
Public identifier |
identifier:
|
Type : string
|
Public multiple |
multiple:
|
Type : boolean
|
Public openOnFocus |
openOnFocus:
|
Type : boolean
|
Public options |
options:
|
Type : any[]
|
Public optionsDataUrl |
optionsDataUrl:
|
Default value : new BehaviorSubject<string>("")
|
Decorators : WidgetInput
|
Public placeholder |
placeholder:
|
Type : string
|
Public reload |
reload:
|
Default value : new Subject()
|
Decorators : WidgetInput
|
Public resetToDefault |
resetToDefault:
|
Default value : new Subject<any>()
|
Decorators : WidgetInput
|
Public selectedValues |
selectedValues:
|
Type : string[]
|
Public showAllPlaceholder |
showAllPlaceholder:
|
Type : boolean
|
Public tabIndex |
tabIndex:
|
Type : number
|
Public valueChanged |
valueChanged:
|
Default value : new ReplaySubject<any>(1)
|
Decorators : WidgetOutput
|
Public valueKey |
valueKey:
|
Type : string
|
import {
WidgetComponent,
WidgetConfiguration,
WidgetConfigure,
WidgetInput,
WidgetOutput,
} from "../widget.metadata";
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
TemplateRef,
ViewChild,
} from "@angular/core";
import { getOrDefault, WidgetConfig } from "../widget.configuration";
import { BehaviorSubject, combineLatest, ReplaySubject, Subject } from "rxjs";
import { WidgetframeService } from "../widgetframe/widgetframe.service";
import {
debounceTime,
filter,
flatMap,
startWith,
takeUntil,
} from "rxjs/operators";
import { NgUnsubscribe } from "../../ng-unsubscribe";
import { CurrentLocaleService } from "../../components/i18n";
import { notNullOrEmpty } from "../../components/util";
import {
LocalStorageEntry,
LocalStorageService,
} from "../../components/local-storage/local-storage.service";
import {
DeletionMode,
Scope,
} from "../../components/local-storage/local-storage-constants";
import { GroupByStrategy } from "../../components/combo/nm-combo.api";
import { NmComboComponent } from "../../components/combo/nm-combo.component";
interface SelectComboConfiguration {
/**
* Tabulator click event order(@default:0)
*/
tabIndex: number;
/**
* Placeholder string to display
*/
placeholder: string;
/**
* `true` to disable the component (@default:false)
*/
disabled: boolean;
/**
* `true` to show the clear button (@default:true)
*/
clearable: boolean;
/**
* Value(relates to select options) identifier key (@default:identifier)
*/
valueKey: string;
/**
* Value(relates to select options) displayed description key (@default:description)
*/
displayKey: string;
/**
* Open options on focus (example over tabulator) (@default:false)
*/
openOnFocus: boolean;
/**
* Id string-array of preselected values(relates to select options) (identifiers)
*/
preselectedValues: string[];
/**
* Allow a empty value as option (@default:true)
*/
allowEmpty: boolean;
/**
* Identifier and name of this field
*/
identifier: string;
/**
* Fetch options of the select element from a url.
*/
optionsDataUrl: string;
/**
* The key of embedded options-data in response of optionsDataUrl
*/
optionsDataKey: string;
/**
* Sets the custom css class
*/
customClass: string;
/**
* If the data contains groups, this field either contains the parent reference or the child options
*/
groupKey: string;
/**
* "nested", groupKey should contain an array of options, "parent-reference": child options reference the valueKey field of their parent
*/
groupStrategy: GroupByStrategy;
/**
* Allow multiple selection (@default: false)
*/
multiple: boolean;
/**
* Show "All" in combo trigger when all values are selected (@default: false)
*/
showAllPlaceholder: boolean;
}
@WidgetComponent("nm-select-combo")
@Component({
selector: "nm-select-combo",
templateUrl: "./select-combo.component.html",
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class SelectComboComponent {
@WidgetConfiguration()
public configuration: WidgetConfig<SelectComboConfiguration>;
public _unsubscribe = NgUnsubscribe.create();
public _optionsDataUrl: string;
public _optionsDataKey: string;
public _preselectedValues: string[];
public _selectionLocalstorageEntry: LocalStorageEntry;
public _allLocalstorageEntry: LocalStorageEntry;
public identifier: string;
public options: any[];
public selectedValues: string[];
public valueKey: string;
public displayKey: string;
public tabIndex: number;
public openOnFocus: boolean;
public clearable: boolean;
public disabled: boolean;
public allowEmpty: boolean;
public filterPlaceholder: string;
public placeholder: string;
public customClass: string;
public groupKey: string;
public groupStrategy: GroupByStrategy;
public multiple: boolean;
public hide: boolean = false;
public showAllPlaceholder: boolean;
@WidgetInput("options-url")
public optionsDataUrl = new BehaviorSubject<string>("");
@WidgetInput("reload-options")
public reload = new Subject();
@WidgetInput("hide")
public hideChannel = new Subject<boolean>();
@WidgetInput()
public resetToDefault = new Subject<any>();
@WidgetOutput("option-selected")
public valueChanged = new ReplaySubject<any>(1);
@WidgetOutput("allSelected")
public allSelected = new ReplaySubject<boolean>(1);
@ViewChild("combo")
public combo: NmComboComponent;
constructor(
protected _widgetframeService: WidgetframeService,
protected _currentLocaleService: CurrentLocaleService,
protected cdr: ChangeDetectorRef,
protected localstorageService: LocalStorageService
) {}
@WidgetConfigure()
public configureWidget(
configuration: WidgetConfig<SelectComboConfiguration>
) {
this.valueKey = getOrDefault(
configuration.configuration.valueKey,
"identifier"
);
this.displayKey = getOrDefault(
configuration.configuration.displayKey,
"description"
);
this.tabIndex = getOrDefault(configuration.configuration.tabIndex, 0);
this.openOnFocus = getOrDefault(
configuration.configuration.openOnFocus,
false
);
this.clearable = getOrDefault(configuration.configuration.clearable, true);
this.disabled = getOrDefault(configuration.configuration.disabled, false);
this._preselectedValues = getOrDefault(
configuration.configuration.preselectedValues,
[]
);
// todo PIMCORE-6734 allow empty option
this.allowEmpty = getOrDefault(
configuration.configuration.allowEmpty,
true
);
this.identifier = getOrDefault(
configuration.configuration.identifier,
"select-combo-field"
);
this.customClass = getOrDefault(
configuration.configuration.customClass,
""
);
this.groupKey = configuration.configuration.groupKey;
this.groupStrategy = configuration.configuration.groupStrategy;
this.multiple = getOrDefault(configuration.configuration.multiple, false);
this._optionsDataUrl = configuration.configuration.optionsDataUrl;
this._optionsDataKey = configuration.configuration.optionsDataKey;
this.placeholder = configuration.configuration.placeholder;
this.showAllPlaceholder = configuration.configuration.showAllPlaceholder;
if (this._optionsDataUrl && !this._optionsDataKey) {
console.error(
'"_optionsDataKey" for widget "',
this.identifier,
'" missing!'
);
}
let localStorageKey = configuration.configuration["local-storage-key"];
if (localStorageKey) {
this._selectionLocalstorageEntry =
this.localstorageService.getLocalStorageEntry(
localStorageKey,
Scope.USER,
DeletionMode.RESET
);
if (this.showAllPlaceholder) {
this._allLocalstorageEntry =
this.localstorageService.getLocalStorageEntry(
"allSelected-" + localStorageKey,
Scope.USER,
DeletionMode.RESET
);
}
}
combineLatest([
this.optionsDataUrl.asObservable().pipe(
startWith(this._optionsDataUrl),
filter((url) => !!url)
),
this._currentLocaleService.getCurrentLocale(),
this.reload.asObservable().pipe(startWith(null)),
])
.pipe(
takeUntil(this._unsubscribe),
debounceTime(50),
flatMap((data) => {
return this._widgetframeService.getData(this._optionsDataUrl);
})
)
.subscribe((response) => {
if (response) {
this.options = response._embedded[this._optionsDataKey];
this.setPreselectValues();
}
});
this.hideChannel
.asObservable()
.pipe(takeUntil(this._unsubscribe))
.subscribe((hide) => {
this.hide = hide;
this.cdr.detectChanges();
});
this.resetToDefault
.asObservable()
.pipe(takeUntil(this._unsubscribe))
.subscribe((reset) => {
this.selectedValues = [];
if (this._selectionLocalstorageEntry) {
this._selectionLocalstorageEntry.clear();
}
this.setPreselectValues();
this.cdr.detectChanges();
});
}
public onChange(value: any) {
let _values = Array.isArray(value) ? value : [value];
this.selectedValues = _values;
this.valueChanged.next(_values);
if (this._selectionLocalstorageEntry) {
this._selectionLocalstorageEntry.value = JSON.stringify(_values);
}
}
private setPreselectValues() {
const flattened = this.combo._api.getFlatComboOptions(
this.options,
this.groupKey
);
// check for case @WidgetInput("options-url") changed and preselected value not exist in new options
if (notNullOrEmpty(this.selectedValues)) {
this.setValidSelectedValues(this.selectedValues, flattened);
} else {
if (notNullOrEmpty(this._preselectedValues)) {
this.setValidSelectedValues(this._preselectedValues, flattened);
} else if (
this._selectionLocalstorageEntry &&
this._selectionLocalstorageEntry.exists()
) {
this.selectedValues = JSON.parse(
this._selectionLocalstorageEntry.value
);
} else {
this.selectedValues = flattened
.filter((option) => option.default === true)
.map((option) => option[this.valueKey]);
}
}
this.isAllSelected(this.selectedValues.length === flattened.length);
this.valueChanged.next(this.selectedValues);
this.cdr.markForCheck();
}
private setValidSelectedValues(values: string[], options: any[]) {
let optionValueIDs = options.map((option) => option[this.valueKey]);
this.selectedValues = values.filter((valueId) =>
optionValueIDs.includes(valueId)
);
}
isAllSelected(allSelected) {
this.allSelected.next(allSelected);
if (this._allLocalstorageEntry) {
this._allLocalstorageEntry.value = allSelected;
}
}
}
<mat-form-field
*ngIf="!hide"
id="{{ identifier }}"
class="mat-body {{ customClass }}"
>
<nm-combo
class="combo"
tabIndex="{{ tabIndex }}}"
[options]="options"
[valueKey]="valueKey"
[displayKey]="displayKey"
[filterPlaceholder]="filterPlaceholder | translate"
[openOnFocus]="openOnFocus"
[(value)]="selectedValues"
(valueChange)="onChange($event)"
[clearable]="clearable"
[disabled]="disabled"
[placeholder]="placeholder | translate"
[groupKey]="groupKey"
[groupStrategy]="groupStrategy"
[multiple]="multiple"
[showAllPlaceholder]="showAllPlaceholder"
(allSelected)="isAllSelected($event)"
#combo
>
<ng-template nmComboOptionGroup let-option>
{{ option.groupName }}
</ng-template>
</nm-combo>
</mat-form-field>