@WidgetComponent
File
Metadata
providers |
WidgetframeService
|
selector |
nm-product-text-list |
styleUrls |
textlist.component.scss |
templateUrl |
./textlist.component.html |
Index
Widget inputs
|
|
|
|
|
Widget outputs
|
|
|
Properties
|
|
Methods
|
|
Constructor
constructor(_widgetframeService: WidgetframeService, _appdataStore: AppdataStore)
|
|
Parameters :
Name |
Type |
Optional |
_widgetframeService |
WidgetframeService
|
no
|
_appdataStore |
AppdataStore
|
no
|
|
Methods
changeViewmode
|
changeViewmode()
|
|
|
Protected
configureWidget
|
configureWidget(configuration: WidgetConfig)
|
Decorators : WidgetConfigure
|
|
|
onExternalModelChange
|
onExternalModelChange(value: )
|
|
|
Public
_id
|
_id:
|
Decorators : WidgetId
|
|
Private
changedValue
|
changedValue: Subject<any>
|
Type : Subject<any>
|
Default value : new Subject<any>()
|
Decorators : WidgetOutput
|
|
Emits the text value when it is changed
|
Public
cols
|
cols: any[]
|
Type : any[]
|
|
Public
editable
|
editable: boolean
|
Type : boolean
|
Default value : false
|
|
Public
hideOnEmpty
|
hideOnEmpty: boolean
|
Type : boolean
|
Default value : false
|
|
Public
placeholder
|
placeholder: string
|
Type : string
|
Default value : "Text"
|
|
Public
productNo
|
productNo:
|
Default value : new Subject<any>()
|
Decorators : WidgetInput
|
|
Sets product number for loading the product texts if 'remotedData' configuration option is enabled,
and sets the text data directly otherwise
|
Public
reload
|
reload:
|
Default value : new Subject<any>()
|
Decorators : WidgetInput
|
|
|
Public
remoteData
|
remoteData: boolean
|
Type : boolean
|
Default value : true
|
|
Public
resetChannel
|
resetChannel:
|
Default value : new Subject<any>()
|
Decorators : WidgetInput
|
|
|
Public
texts
|
texts: BehaviorSubject<any[]>
|
Type : BehaviorSubject<any[]>
|
Default value : new BehaviorSubject([])
|
|
Private
unsubscribe
|
unsubscribe:
|
Default value : NgUnsubscribe.create()
|
|
viewmode
|
viewmode: string
|
Type : string
|
Default value : "html"
|
|
Public
withHeader
|
withHeader: boolean
|
Type : boolean
|
Default value : true
|
|
import {
combineLatest as observableCombineLatest,
Subject,
BehaviorSubject,
} from "rxjs";
import { takeUntil, mergeMap, distinctUntilChanged } from "rxjs/operators";
import { Component, NgZone } from "@angular/core";
import { AppdataStore } from "../../../components/appdata/appdata.store";
import { WidgetframeService } from "../../widgetframe/widgetframe.service";
import { getOrDefault, WidgetConfig } from "../../widget.configuration";
import { NgUnsubscribe } from "../../../ng-unsubscribe";
import {
WidgetComponent,
WidgetId,
WidgetConfiguration,
WidgetConfigure,
WidgetInput,
WidgetOutput,
} from "../../widget.metadata";
import * as uriTemplates_ from "uri-templates";
const uriTemplates = uriTemplates_;
export interface TextListConfiguration {
/**
* Sets the title shown in the text list header
*/
title: string;
/**
* Sets CSS class name for the text list header
*/
header: string;
/**
* Displays the text type and the text as two columns side by side @default(false)
*/
twoColumns?: boolean;
/**
* Defines the context where the text list is used (e.g. the value 'content' is used in content management app)
*/
context?: string;
/**
* Allows loading of the text in the text list from url @default(true)
*/
remoteData?: boolean;
/**
* Hides the text list if there is no text @default(false)
*/
hideOnEmpty?: boolean;
/**
* Shows a header for the text list @default(true)
*/
withHeader?: boolean;
/**
* Sets a placeholder text in the text list when there is no text
*/
placeholder: string;
/**
* Enables the editing of the text in the text list @default(false)
*/
editable?: boolean;
}
@WidgetComponent("nm-product-text-list")
@Component({
selector: "nm-product-text-list",
templateUrl: "./textlist.component.html",
styleUrls: ["./textlist.component.scss"],
providers: [WidgetframeService],
})
export class TextListWidgetComponent {
public cols: any[];
public editable: boolean = false;
public remoteData: boolean = true;
public hideOnEmpty: boolean = false;
public withHeader: boolean = true;
public placeholder: string = "Text";
private unsubscribe = NgUnsubscribe.create();
public texts: BehaviorSubject<any[]> = new BehaviorSubject([]);
viewmode: string = "html";
/**
* Sets product number for loading the product texts if 'remotedData' configuration option is enabled,
* and sets the text data directly otherwise
*/
@WidgetInput()
public productNo = new Subject<any>();
/**
* Reloads the text list
*/
@WidgetInput()
public reload = new Subject<any>();
/**
* Clears the text list
*/
@WidgetInput("reset")
public resetChannel = new Subject<any>();
/**
* Emits the text value when it is changed
*/
@WidgetOutput("changedValue")
private changedValue: Subject<any> = new Subject<any>();
@WidgetId()
public _id;
@WidgetConfiguration()
public configuration: WidgetConfig<TextListConfiguration>;
constructor(
private _widgetframeService: WidgetframeService,
private _appdataStore: AppdataStore
) {
this.cols = [
{ field: "description", header: "tab.head.att.name" },
{ field: "value", header: "" },
];
}
@WidgetConfigure()
protected configureWidget(
configuration: WidgetConfig<TextListConfiguration>
) {
this.remoteData = getOrDefault(
configuration.configuration.remoteData,
true
);
this.hideOnEmpty = configuration.configuration.hideOnEmpty;
this.withHeader = getOrDefault(
configuration.configuration.withHeader,
true
);
this.placeholder = configuration.configuration.placeholder;
let href = "";
if (this.remoteData === true) {
href = configuration._links["texts"]["href"];
}
let template = uriTemplates(href);
this.editable = configuration.configuration.editable
? configuration.configuration.editable
: false;
observableCombineLatest(
this.productNo.asObservable().pipe(distinctUntilChanged()),
this.reload.asObservable(),
(product, reloadEvent) => {
this.viewmode = "html";
if (this.remoteData) {
return template.fill({ product: product });
} else {
return product;
}
}
)
.pipe(
mergeMap((value) => {
if (this.remoteData) {
return this._widgetframeService.getData(value);
} else {
return [{ values: [value] }];
}
})
)
.subscribe(
(data) => {
this.texts.next(data["values"]);
},
(error) => {
if (this.remoteData) {
var err = JSON.parse(error.text());
} else {
var err = JSON.parse(error);
}
}
);
this.resetChannel
.asObservable()
.pipe(takeUntil(this.unsubscribe))
.subscribe((reset) => {
this.texts.next([]);
this.viewmode = "html";
return null;
});
}
changeViewmode() {
if (this.viewmode == "text") {
this.viewmode = "html";
} else {
this.viewmode = "text";
}
}
onChange() {
let currentTexts: any[] = [];
this.texts.subscribe((data) => (currentTexts = data));
this.changedValue.next(currentTexts[0]);
}
onExternalModelChange(value) {
if (this.texts) {
let currentText = this.texts.value[0];
currentText.value = value;
this.changedValue.next(currentText);
}
}
}
<nm-widgetframe
(toggleViewmode)="changeViewmode()"
[header]="configuration.configuration['header']"
[hasButton]="true"
[toolbarInvisible]="!withHeader"
widgetId="{{ _id }}"
*ngIf="!(hideOnEmpty && (texts | async)?.length == 0)"
>
<div slot="title" class="nm-widgetframe__title">
{{ configuration.configuration["title"] | translate }}
</div>
<div slot="content" class="nm-widgetframe__content">
<div
class="nm-attribute-list"
[ngClass]="configuration.configuration.twoColumns ? '--twoColumns' : ''"
>
<p-toggleButton
(click)="changeViewmode()"
*ngIf="!withHeader"
offIcon="fa fa-pencil"
onIcon="fa fa-check"
offLabel=""
onLabel=""
pTooltip="{{
'app.iPimContentMGT.frontend.text.HTML.switch' | translate
}}"
class="in-content-toggle-btn"
></p-toggleButton>
<ng-container *ngFor="let text of texts | async">
<div class="nm-attribute-list-elements nm-texts">
<div
*ngIf="configuration.configuration['context'] !== 'content'"
class="nm-attribute-list-description"
>
{{ text.description }}
</div>
<div
*ngIf="viewmode === 'text'"
[className]="
configuration.configuration['context'] !== 'content'
? 'nm-attribute-list-value'
: 'nm-attribute-list-value-full-width'
"
>
<ng-container
*ngIf="
configuration.configuration['context'] === 'content';
else plain
"
>
<nm-tiny-text-editor
(valueChanged)="onExternalModelChange($event)"
[value]="text.value"
>
</nm-tiny-text-editor>
</ng-container>
<ng-template #plain>
<mat-form-field class="full-width" *ngIf="editable">
<textarea
class="fillContainer"
(input)="onChange()"
rows="7"
placeholder="{{ placeholder | translate }}"
spellcheck="true"
[(ngModel)]="text.value"
matInput
></textarea>
</mat-form-field>
</ng-template>
<div *ngIf="!editable">{{ text.value }}</div>
</div>
<div
*ngIf="viewmode === 'html'"
[innerHTML]="text.value | sanitizeHtml"
[className]="
configuration.configuration['context'] !== 'content'
? 'nm-attribute-list-value'
: 'nm-attribute-list-value-full-width'
"
></div>
<!--
<div *ngIf="text.hasTooltip" class="nm-attribute-list-value">
{{text.value}}
</div>
<div *ngIf="!text.hasTooltip" class="nm-attribute-list-value">{{text.value}}</div>
-->
</div>
</ng-container>
</div>
</div>
</nm-widgetframe>
Legend
Html element with directive