nm-search-input
src/app/shared/widgets/search/input/search-input.component.ts
ControlValueAccessor
OnChanges
changeDetection | ChangeDetectionStrategy.OnPush |
providers |
{
: , : (() => ), : true,
}
|
selector | nm-search-input |
styleUrls | search-input.component.scss |
templateUrl | ./search-input.component.html |
Widget inputs |
Widget outputs |
Properties |
|
Methods |
Inputs |
Outputs |
constructor(cdr: ChangeDetectorRef)
|
||||||
Parameters :
|
field
|
Type: |
floatingLabel
|
|
locale
|
|
lookups
|
|
placeholder
|
|
triggerAsChipList
|
Enables/Disables display for the selected values in
Type:
Default value: |
enterPressed
|
$event type: EventEmitter
|
event
|
$event type: EventEmitter
|
Public dateChanged |
dateChanged()
|
Returns :
void
|
dateInputKeydown | ||||
dateInputKeydown(event: )
|
||||
Parameters :
Returns :
void
|
Public externalValueChanged | ||||||
externalValueChanged(newValue: string)
|
||||||
Parameters :
Returns :
void
|
getIconForSearchMode | ||||
getIconForSearchMode(value: )
|
||||
Parameters :
Returns :
"alpha-s-box-outline" | "alpha-p-box-outline" | "alpha-k-box-outline" | "alpha-c-box-outline"
|
hasValue |
hasValue()
|
Returns :
boolean
|
ngOnChanges | ||||||
ngOnChanges(changes: SimpleChanges)
|
||||||
Parameters :
Returns :
void
|
onEnterPressed | ||||
onEnterPressed(event: )
|
||||
Parameters :
Returns :
void
|
registerOnChange | ||||
registerOnChange(fn: )
|
||||
Parameters :
Returns :
void
|
registerOnTouched | ||||||
registerOnTouched(fn: any)
|
||||||
Parameters :
Returns :
void
|
resetDateValue | ||||
resetDateValue(event: )
|
||||
Parameters :
Returns :
boolean
|
resetValue | ||||
resetValue(event: )
|
||||
Parameters :
Returns :
boolean
|
setDisabledState | ||||||
setDisabledState(isDisabled: boolean)
|
||||||
Parameters :
Returns :
void
|
setValue | ||||
setValue(value: )
|
||||
Parameters :
Returns :
void
|
Public valueChanged | ||||||
valueChanged(event?: any)
|
||||||
Parameters :
Returns :
void
|
writeValue | ||||||
writeValue(obj: any)
|
||||||
Parameters :
Returns :
void
|
Public categoryValue |
categoryValue:
|
datePicker |
datePicker:
|
Type : OwlDateTimeComponent<Date>
|
Decorators : ViewChild
|
dateTimePicker |
dateTimePicker:
|
Type : OwlDateTimeComponent<Date>
|
Decorators : ViewChild
|
Public dateValue |
dateValue:
|
Public displayIcon |
displayIcon:
|
Public options |
options:
|
Default value : new ReplaySubject<any[]>(1)
|
propagateChange |
propagateChange:
|
Default value : (_: any) => {}
|
Public value |
value:
|
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
EventEmitter,
forwardRef,
Input,
OnChanges,
Output,
SimpleChanges,
ViewChild,
} from "@angular/core";
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from "@angular/forms";
import {
deepCopy,
openPickerOverKeyboard,
parseDate,
toDate,
} from "../../../components/util/util.service";
import {
FormEventPayload,
FormWidgetField,
} from "../advanced/search-advanced.component";
import { ReplaySubject } from "rxjs";
import { OwlDateTimeComponent } from "ng-pick-datetime";
import { UtilService } from "../../../components/util/util.service";
@Component({
selector: "nm-search-input",
templateUrl: "./search-input.component.html",
styleUrls: ["./search-input.component.scss"],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => SearchInputComponent),
multi: true,
},
],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class SearchInputComponent implements ControlValueAccessor, OnChanges {
@Input() public field: FormWidgetField;
@Input() public lookups;
@Input() public locale;
@Input() public placeholder;
@Input() public floatingLabel;
/**
* Enables/Disables display for the selected values in `MULTI_LOOKUP` attributes as chips.
* @default(false)
*/
@Input("triggerAsChipList") public triggerAsChipList: boolean = false;
@Output() public event = new EventEmitter<FormEventPayload>();
@Output() public enterPressed = new EventEmitter();
@ViewChild("datepicker", { static: false })
datePicker: OwlDateTimeComponent<Date>;
@ViewChild("datetimepicker", { static: false })
dateTimePicker: OwlDateTimeComponent<Date>;
public value;
public dateValue;
// Value for initializing the category
public categoryValue;
public displayIcon;
public options = new ReplaySubject<any[]>(1);
constructor(private cdr: ChangeDetectorRef) {}
public externalValueChanged(newValue: string) {
this.value = deepCopy(newValue);
this.valueChanged();
}
public valueChanged(event?: any) {
if (this.field.eventField) {
const payload = event ? event : this.value;
this.event.next({ field: this.field.identifier, payload });
} else {
if (event !== undefined) {
this.value = event;
}
if (this.value) {
this.displayIcon = this.value.icon;
}
this.propagateChange(this.value);
}
this.cdr.markForCheck();
}
public dateChanged() {
if (this.dateValue) {
this.value = this.field.formatDate
? this.dateValue.toISOString()
: this.dateValue;
} else {
this.value = null;
}
this.propagateChange(this.value);
this.cdr.markForCheck();
}
propagateChange = (_: any) => {};
registerOnChange(fn) {
this.propagateChange = fn;
}
registerOnTouched(fn: any): void {}
writeValue(obj: any): void {
this.value = obj;
if (this.field.type === "DATE" || this.field.type === "DATE_TIME") {
if (this.value) {
this.dateValue = this.field.formatDate
? parseDate(this.value, null)
: toDate(this.value);
} else {
this.dateValue = null;
}
}
if (!obj) {
this.categoryValue = {};
this.categoryValue = null;
}
if (this.field.type === "CATEGORY" && !obj) {
this.categoryValue = null;
}
this.cdr.markForCheck();
}
setValue(value) {
this.value = value;
this.valueChanged();
}
resetDateValue(event) {
this.dateValue = null;
this.dateChanged();
event.preventDefault();
event.stopPropagation();
return false;
}
resetValue(event) {
this.value = null;
event.preventDefault();
event.stopPropagation();
this.propagateChange(null);
this.cdr.markForCheck();
return false;
}
ngOnChanges(changes: SimpleChanges): void {
if (changes.lookups || changes.locale || changes.field) {
const options = this.lookups?.[this.locale]?.[this.field.lookupSource];
if (options != null) {
this.options.next(options);
}
}
}
hasValue(): boolean {
return this.value && (!Array.isArray(this.value) || this.value.length > 0);
}
setDisabledState(isDisabled: boolean): void {}
dateInputKeydown(event) {
openPickerOverKeyboard(
event,
this.field.type,
this.datePicker,
this.dateTimePicker
);
}
onEnterPressed(event) {
event.preventDefault();
this.enterPressed.emit();
}
getIconForSearchMode(value) {
if (value === "SEARCH_MODE_STANDARD") {
return "alpha-s-box-outline";
} else if (value === "SEARCH_MODE_PROFESSIONAL") {
return "alpha-p-box-outline";
} else if (value === "SEARCH_MODE_COMFORT") {
if (this.locale.startsWith("de")) {
return "alpha-k-box-outline";
} else {
return "alpha-c-box-outline";
}
}
return "alpha-s-box-outline";
}
}
<div [ngSwitch]="field.type" class="form-input-row">
<ng-container *ngSwitchCase="'PLAIN_STRING'">
<mat-form-field [ngClass]="{ virgin: !value }">
<mat-label *ngIf="floatingLabel">{{
floatingLabel | translate
}}</mat-label>
<input
autocomplete="off"
matInput
[placeholder]="placeholder"
[(ngModel)]="value"
(ngModelChange)="valueChanged()"
(keydown.enter)="onEnterPressed($event)"
/>
<button
mat-icon-button
matSuffix
aria-label="Clear"
color="primary"
*ngIf="hasValue()"
(click)="resetValue($event)"
>
<mat-icon color="primary" class="fade-in">close</mat-icon>
</button>
</mat-form-field>
</ng-container>
<ng-container *ngSwitchCase="'INTEGER_NUMBER'">
<mat-form-field [ngClass]="{ virgin: !value }">
<mat-label *ngIf="floatingLabel">{{
floatingLabel | translate
}}</mat-label>
<input
autocomplete="off"
type="number"
matInput
[placeholder]="placeholder"
[(ngModel)]="value"
(ngModelChange)="valueChanged()"
(keydown.enter)="onEnterPressed($event)"
min="{{ field.min == null ? '' : field.min }}"
max="{{ field.max == null ? '' : field.max }}"
/>
<button
mat-icon-button
matSuffix
aria-label="Clear"
color="primary"
*ngIf="hasValue()"
(click)="resetValue($event)"
>
<mat-icon color="primary" class="fade-in">close</mat-icon>
</button>
</mat-form-field>
</ng-container>
<ng-container *ngSwitchCase="'DATE'">
<mat-form-field
class="nm-date-time-input"
(click)="datepicker.open()"
[ngClass]="{ virgin: !dateValue }"
>
<mat-label *ngIf="floatingLabel">{{
floatingLabel | translate
}}</mat-label>
<input
matInput
autocomplete="off"
[placeholder]="placeholder"
[owlDateTime]="datepicker"
[(ngModel)]="dateValue"
(ngModelChange)="dateChanged()"
(keydown)="dateInputKeydown($event)"
/>
<button
mat-icon-button
matSuffix
aria-label="Clear"
color="primary"
*ngIf="hasValue()"
(click)="resetDateValue($event)"
tabIndex="-1"
>
<mat-icon color="primary" class="fade-in">close</mat-icon>
</button>
<button
mat-button
matSuffix
mat-icon-button
aria-label="date_range"
[owlDateTimeTrigger]="datepicker"
tabIndex="-1"
>
<mat-icon>event</mat-icon>
</button>
</mat-form-field>
<owl-date-time pickerType="calendar" #datepicker></owl-date-time>
</ng-container>
<ng-container *ngSwitchCase="'DATE_TIME'">
<mat-form-field
class="nm-date-time-input"
(click)="datepicker.open()"
[ngClass]="{ virgin: !dateValue }"
>
<mat-label *ngIf="floatingLabel">{{
floatingLabel | translate
}}</mat-label>
<input
matInput
autocomplete="off"
[placeholder]="placeholder"
[owlDateTime]="datepicker"
[(ngModel)]="dateValue"
(ngModelChange)="dateChanged()"
(keydown)="dateInputKeydown($event)"
/>
<button
mat-icon-button
matSuffix
aria-label="Clear"
color="primary"
*ngIf="hasValue()"
(click)="resetDateValue($event)"
tabIndex="-1"
>
<mat-icon color="primary" class="fade-in">close</mat-icon>
</button>
<button
mat-button
matSuffix
mat-icon-button
aria-label="date_range"
[owlDateTimeTrigger]="datepicker"
tabIndex="-1"
>
<mat-icon>event</mat-icon>
</button>
</mat-form-field>
<owl-date-time pickerType="both" #datepicker></owl-date-time>
</ng-container>
<mat-form-field *ngSwitchCase="'LOOKUP'" [ngClass]="{ virgin: !value }">
<mat-label *ngIf="floatingLabel">{{ floatingLabel | translate }}</mat-label>
<nm-combo
class="combo"
tabIndex="0"
[options]="options | async"
[valueKey]="'value'"
[displayKey]="'label'"
[clearable]="false"
[filterPlaceholder]="'placeholder.search' | translate"
[placeholder]="placeholder"
[emptyOption]="field.default ? null : ''"
[name]="'lookup'"
[(ngModel)]="value"
(ngModelChange)="valueChanged()"
>
<ng-template nmComboOption let-option>
{{ option.label | translate }}
</ng-template>
<ng-template nmComboTrigger let-selection="selection">
{{ selection[0]?.label | translate }}
</ng-template>
</nm-combo>
<button
mat-icon-button
matSuffix
aria-label="Clear"
color="primary"
*ngIf="hasValue()"
(click)="resetDateValue($event)"
>
<mat-icon color="primary" class="fade-in">close</mat-icon>
</button>
</mat-form-field>
<mat-form-field *ngSwitchCase="'MENU'" class="nm-formfiled-menu">
<mat-label *ngIf="floatingLabel">{{ floatingLabel | translate }}</mat-label>
<mat-select
*ngIf="hasValue()"
[placeholder]="placeholder"
[(value)]="value"
(valueChange)="valueChanged()"
>
<mat-select-trigger>
<mat-icon [svgIcon]="getIconForSearchMode(value)"></mat-icon>
</mat-select-trigger>
<mat-option *ngIf="!field.default"></mat-option>
<mat-option *ngFor="let value of options | async" [value]="value.value">
<mat-icon [svgIcon]="getIconForSearchMode(value.value)"></mat-icon>
{{ value.label }}</mat-option
>
</mat-select>
</mat-form-field>
<mat-form-field *ngSwitchCase="'MULTI_LOOKUP'" [ngClass]="{ virgin: !value }">
<mat-label *ngIf="floatingLabel">{{ floatingLabel | translate }}</mat-label>
<nm-combo
class="combo"
tabIndex="0"
[options]="options | async"
[valueKey]="'value'"
[displayKey]="'label'"
[filterPlaceholder]="'placeholder.search' | translate"
[placeholder]="placeholder"
[multiple]="true"
[clearable]="hasValue()"
[name]="'lookup'"
[(ngModel)]="value"
(ngModelChange)="externalValueChanged($event)"
[trigger]="triggerAsChipList ? 'chips' : 'plain'"
>
<ng-template nmComboOption let-option>
{{ option.label | translate }}
</ng-template>
</nm-combo>
</mat-form-field>
<nm-context-selector
*ngSwitchCase="'CONTEXT'"
tabIndex="0"
[contexts]="options | async"
[placeholder]="floatingLabel ? floatingLabel : (placeholder | translate)"
[value]="value"
field="identifier"
(identifierChange)="valueChanged($event)"
>
</nm-context-selector>
<nm-category-select-control
*ngSwitchCase="'CATEGORY'"
[placeholder]="placeholder"
[value]="value"
(change)="valueChanged($event)"
></nm-category-select-control>
<div *ngSwitchDefault>
{{ field | json }}
</div>
</div>