import {ComponentInitParams, Control, paramParsers} from '../../controls.js'; import { Expression, Literal, looksLikeSerializedExpression, unserializeExpression } from '../../../../shared-dsl/client/wire-dsl.js'; export class AmeRevEventButton extends Control { public readonly eventName: string; public readonly eventData: Expression | null = null; /** * Whether to wrap the button in a

tag. */ public readonly wrap: boolean = false; public readonly customLabel: KnockoutObservable = ko.observable(''); public readonly effectiveLabel: KnockoutComputed; protected readonly iconClass: KnockoutObservable; public readonly customIconClass: KnockoutObservable = ko.observable(''); public readonly effectiveIconClass: KnockoutComputed; public readonly kind: 'button' | 'link' = 'button'; constructor(params: ComponentInitParams, $element: JQuery) { super(params, $element); if (typeof params['eventName'] === 'undefined') { throw new Error('AmeEventButton requires an "eventName" parameter to be defined.'); } this.eventName = (params['eventName'] + ''); if (typeof params['wrap'] !== 'undefined') { this.wrap = !!(params['wrap']); } if (typeof params['kind'] !== 'undefined') { this.kind = params['kind'] === 'link' ? 'link' : 'button'; } //Not used as of this writing, but could be used in the future for passing //additional data to the event handler. if (typeof params['eventData'] !== 'undefined') { if (looksLikeSerializedExpression(params['eventData'])) { this.eventData = unserializeExpression(params['eventData']); } else { this.eventData = new Literal(params['eventData']); } } this.effectiveLabel = ko.pureComputed(() => { return this.customLabel() || this.label(); }); this.iconClass = paramParsers.string(params, 'iconClass', '', this.context); this.effectiveIconClass = ko.pureComputed(() => { return this.customIconClass() || this.iconClass(); }); this.elementClasses.unshift('ame-event-button-control', 'ame-rev-event-button'); if (this.kind === 'button') { this.elementClasses.unshift('button'); } else if (this.kind === 'link') { this.elementClasses.push('ame-rev-event-button-link'); } if (this.id) { this.elementId = this.id; } } triggerEvent(): void { const eventData = { data: (this.eventData ? this.eventData.evaluate(this.context) : null), eventButton: this }; this.findEventTarget()?.dispatchEvent(new CustomEvent(this.eventName, { detail: eventData, bubbles: true, })); } private cachedEventTarget: EventTarget | null = null; private triedToFindEventTarget: boolean = false; private findEventTarget(): EventTarget | null { if (this.triedToFindEventTarget) { return this.cachedEventTarget; } this.triedToFindEventTarget = true; const $child = this.findChild('input, button, a, p'); if ($child.length === 0) { throw new Error( 'AmeRevEventButton could not find its child element to dispatch the event on.' ); } this.cachedEventTarget = $child[0]; return this.cachedEventTarget; } static buttonContentTemplate = ``; static buttonTemplate = ` ${AmeRevEventButton.buttonContentTemplate} `; static componentName = 'ame-rev-event-button'; static template = `

${AmeRevEventButton.buttonTemplate}

${AmeRevEventButton.buttonTemplate} `; }