@WidgetComponent

nm-select-combo

File

src/app/shared/widgets/select-combo/select-combo.component.ts

Metadata

changeDetection ChangeDetectionStrategy.OnPush
selector nm-select-combo
templateUrl ./select-combo.component.html

Index

Widget inputs
Widget outputs
Properties
Methods

Constructor

constructor(_widgetframeService: WidgetframeService, _currentLocaleService: CurrentLocaleService, cdr: ChangeDetectorRef, localstorageService: LocalStorageService)
Parameters :
Name Type Optional
_widgetframeService WidgetframeService no
_currentLocaleService CurrentLocaleService no
cdr ChangeDetectorRef no
localstorageService LocalStorageService no

Methods

Public configureWidget
configureWidget(configuration: WidgetConfig)
Decorators : WidgetConfigure
Parameters :
Name Type Optional
configuration WidgetConfig<SelectComboConfiguration> no
Returns : void
isAllSelected
isAllSelected(allSelected: )
Parameters :
Name Optional
allSelected no
Returns : void
Public onChange
onChange(value: any)
Parameters :
Name Type Optional
value any no
Returns : void
Private setPreselectValues
setPreselectValues()
Returns : void
Private setValidSelectedValues
setValidSelectedValues(values: string[], options: any[])
Parameters :
Name Type Optional
values string[] no
options any[] no
Returns : void

Properties

Public _allLocalstorageEntry
_allLocalstorageEntry: LocalStorageEntry
Type : LocalStorageEntry
Public _optionsDataKey
_optionsDataKey: string
Type : string
Public _optionsDataUrl
_optionsDataUrl: string
Type : string
Public _preselectedValues
_preselectedValues: string[]
Type : string[]
Public _selectionLocalstorageEntry
_selectionLocalstorageEntry: LocalStorageEntry
Type : LocalStorageEntry
Public _unsubscribe
_unsubscribe:
Default value : NgUnsubscribe.create()
Public allowEmpty
allowEmpty: boolean
Type : boolean
Public allSelected
allSelected:
Default value : new ReplaySubject<boolean>(1)
Decorators : WidgetOutput
Public clearable
clearable: boolean
Type : boolean
Public combo
combo: NmComboComponent
Type : NmComboComponent
Decorators : ViewChild
Public configuration
configuration: WidgetConfig<SelectComboConfiguration>
Type : WidgetConfig<SelectComboConfiguration>
Decorators : WidgetConfiguration
Public customClass
customClass: string
Type : string
Public disabled
disabled: boolean
Type : boolean
Public displayKey
displayKey: string
Type : string
Public filterPlaceholder
filterPlaceholder: string
Type : string
Public groupKey
groupKey: string
Type : string
Public groupStrategy
groupStrategy: GroupByStrategy
Type : GroupByStrategy
Public hide
hide: boolean
Type : boolean
Default value : false
Public hideChannel
hideChannel:
Default value : new Subject<boolean>()
Decorators : WidgetInput
Public identifier
identifier: string
Type : string
Public multiple
multiple: boolean
Type : boolean
Public openOnFocus
openOnFocus: boolean
Type : boolean
Public options
options: any[]
Type : any[]
Public optionsDataUrl
optionsDataUrl:
Default value : new BehaviorSubject<string>("")
Decorators : WidgetInput
Public placeholder
placeholder: string
Type : string
Public reload
reload:
Default value : new Subject()
Decorators : WidgetInput
Public resetToDefault
resetToDefault:
Default value : new Subject<any>()
Decorators : WidgetInput
Public selectedValues
selectedValues: string[]
Type : string[]
Public showAllPlaceholder
showAllPlaceholder: boolean
Type : boolean
Public tabIndex
tabIndex: number
Type : number
Public valueChanged
valueChanged:
Default value : new ReplaySubject<any>(1)
Decorators : WidgetOutput
Public valueKey
valueKey: string
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>
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""