diff --git a/src/Webform.js b/src/Webform.js index d0d788fde1..742f2b5db4 100644 --- a/src/Webform.js +++ b/src/Webform.js @@ -782,6 +782,19 @@ export default class Webform extends NestedDataComponent { this.setSubmission(submission); } + /** + * Sets the submission value + * @param {object|null|undefined} submission - The submission to set. + * @param {object|null|undefined} flags - Any flags to apply when setting the submission. + * @return {void} + */ + onSetSubmission(submission, flags = {}) { + this.submissionSet = true; + this.triggerChange(flags); + this.emit('beforeSetSubmission', submission); + this.setValue(submission, flags); + } + /** * Sets a submission and returns the promise when it is ready. * @param {any} submission - The submission to set. @@ -802,10 +815,7 @@ export default class Webform extends NestedDataComponent { ...resolveFlags, }; } - this.submissionSet = true; - this.triggerChange(flags); - this.emit("beforeSetSubmission", submission); - this.setValue(submission, flags); + this.onSetSubmission(submission, flags); return this.submissionReadyResolve(submission); }, (err) => this.submissionReadyReject(err) @@ -1253,7 +1263,6 @@ export default class Webform extends NestedDataComponent { // Mark any components as invalid if in a custom message. errors.forEach((err) => { const { components = [] } = err; - if (err.component) { components.push(err.component); } diff --git a/src/components/_classes/component/Component.js b/src/components/_classes/component/Component.js index b6aaa10be6..0aeca4650a 100644 --- a/src/components/_classes/component/Component.js +++ b/src/components/_classes/component/Component.js @@ -1193,6 +1193,15 @@ export default class Component extends Element { this.componentModal.setOpenModalElement(template || this.getModalPreviewTemplate()); } + /** + * Renders a modal preview template and returns the markup as a string + * @param {object|null|undefined} ctx - The rendering context + * @return {string} - The modal preview markup + */ + renderModalPreview(ctx) { + return this.renderTemplate('modalPreview', ctx || {}); + } + /** * Returns the modal preview template. * @returns {string} - The modal preview template. @@ -1205,7 +1214,7 @@ export default class Component extends Element { modalLabel = { className: 'field-required' }; } - return this.renderTemplate('modalPreview', { + return this.renderModalPreview({ previewText: this.getValueAsString(dataValue, { modalPreview: true }) || this.t('Click to set value'), messages: '', labelInfo: modalLabel, @@ -1259,6 +1268,29 @@ export default class Component extends Element { } } + /** + * Creates the tooltip instance using tippy.js and returns it + * @param {HTMLElement} tooltipEl - HTML element to attach the tooltip + * @param {object|null|undefined} settings - tippy.js options + * @return {import('tippy.js').Tippy} - tippy.js instance + */ + createTooltip(tooltipEl, settings = {}) { + const tooltipAttribute = tooltipEl.getAttribute('data-tooltip'); + const tooltipDataTitle = tooltipEl.getAttribute('data-title'); + const tooltipText = this.interpolate(tooltipDataTitle || tooltipAttribute) + .replace(/(?:\r\n|\r|\n)/g, '
'); + + return tippy(tooltipEl, { + allowHTML: true, + trigger: 'mouseenter click focus', + placement: 'right', + zIndex: 10000, + interactive: true, + ...settings, + content: this.t(this.sanitize(tooltipText), { _userInput: true }), + }); + } + /** * Attaches all the tooltips provided the refs object. * @param {object} toolTipsRefs - The refs for the tooltips within your template. @@ -1267,19 +1299,7 @@ export default class Component extends Element { attachTooltips(toolTipsRefs) { toolTipsRefs?.forEach((tooltip, index) => { if (tooltip) { - const tooltipAttribute = tooltip.getAttribute('data-tooltip'); - const tooltipDataTitle = tooltip.getAttribute('data-title'); - const tooltipText = this.interpolate(tooltipDataTitle || tooltipAttribute) - .replace(/(?:\r\n|\r|\n)/g, '
'); - - this.tooltips[index] = tippy(tooltip, { - allowHTML: true, - trigger: 'mouseenter click focus', - placement: 'right', - zIndex: 10000, - interactive: true, - content: this.t(this.sanitize(tooltipText), { _userInput: true }), - }); + this.tooltips[index] = this.createTooltip(tooltip); } }); } diff --git a/src/components/form/Form.js b/src/components/form/Form.js index b4c909feb1..7ec73f3a2b 100644 --- a/src/components/form/Form.js +++ b/src/components/form/Form.js @@ -726,9 +726,18 @@ export default class FormComponent extends Component { }); } else { - this.subForm.setValue(submission, flags); + this.onSetSubFormValue(submission, flags); } } + /** + * Sets the subform value + * @param {object|null|undefined} submission - The submission to set. + * @param {object|null|undefined} flags - Any flags to apply when setting the submission. + * @return {void} + */ + onSetSubFormValue(submission, flags) { + this.subForm.setValue(submission, flags); + } isEmpty(value = this.dataValue) { return value === null || _.isEqual(value, this.emptyValue) || (this.areAllComponentsEmpty(value?.data) && !value?._id); diff --git a/src/components/signature/Signature.js b/src/components/signature/Signature.js index d493fb2918..2b94fccfee 100644 --- a/src/components/signature/Signature.js +++ b/src/components/signature/Signature.js @@ -196,7 +196,7 @@ export default class SignatureComponent extends Input { } getModalPreviewTemplate() { - return this.renderTemplate('modalPreview', { + return this.renderModalPreview({ previewText: this.dataValue ? `` : this.t('Click to Sign')