diff --git a/src/components/form/Form.js b/src/components/form/Form.js index ff52641e0a..383a5e90c1 100644 --- a/src/components/form/Form.js +++ b/src/components/form/Form.js @@ -233,7 +233,8 @@ export default class FormComponent extends Component { /** * Prints out the value of form components as a datagrid value. */ - getValueAsString(value) { + + getValueAsString(value, options) { if (!value) { return 'No data provided'; } @@ -243,6 +244,37 @@ export default class FormComponent extends Component { if (!value.data || !Object.keys(value.data).length) { return 'No data provided'; } + if (options?.email) { + let result = (` + + + `); + + this.everyComponent((component) => { + if (component.isInputComponent && component.visible && !component.skipInEmail) { + result += (` + + + + + `); + } + }, { + ...options, + fromRoot: true, + }); + + result += (` + +
${component.label}${component.getView(component.dataValue, options)}
+ `); + + return result; + } + if (_.isEmpty(value)) { + return ''; + } + return '[Complex Data]'; } diff --git a/src/components/form/Form.unit.js b/src/components/form/Form.unit.js index d68c847039..9d2d8c5474 100644 --- a/src/components/form/Form.unit.js +++ b/src/components/form/Form.unit.js @@ -19,6 +19,25 @@ describe('Form Component', () => { return Harness.testCreate(FormComponent, comp1); }); + describe('Value inside Nested Form', () => { + it('Should be able to set value to Nested Form Component and check result in the email template', (done) => { + const formElement = document.createElement('div'); + const form = new Webform(formElement); + form.setForm(comp5) + .then(() => { + const textField = form.getComponent(['form', 'textField']); + textField.setValue('123', { modified: true }); + assert.equal(textField.dataValue, '123', 'Should set value'); + const toString = form.getValueAsString(textField.data, { email: true }); + assert.ok(toString.includes('table'), 'Email template should render html table'); + assert.ok(toString.includes(textField.label), 'Email template should have Text Field label'); + assert.ok(toString.includes(textField.dataValue), 'Email template should have Text Field value'); + done(); + }) + .catch(done); + }); + }); + it('Test refreshOn inside NestedForm', (done) => { const formElement = document.createElement('div'); const form = new Webform(formElement); diff --git a/src/components/phonenumber/PhoneNumber.js b/src/components/phonenumber/PhoneNumber.js index bdec35aae4..c927b94596 100644 --- a/src/components/phonenumber/PhoneNumber.js +++ b/src/components/phonenumber/PhoneNumber.js @@ -1,4 +1,5 @@ import TextFieldComponent from '../textfield/TextField'; +import _ from 'lodash'; export default class PhoneNumberComponent extends TextFieldComponent { static schema(...extend) { @@ -27,4 +28,23 @@ export default class PhoneNumberComponent extends TextFieldComponent { get defaultSchema() { return PhoneNumberComponent.schema(); } + + getValueAsString(value, options) { + if (options?.email && this.visible && !this.skipInEmail && _.isObject(value)) { + const result = (` + + + + + + + +
${value.maskName}${value.value}
+ `); + + return result; + } + + return super.getValueAsString(value, options); + } } diff --git a/src/components/phonenumber/PhoneNumber.unit.js b/src/components/phonenumber/PhoneNumber.unit.js index f8895caa15..b099fc33b6 100644 --- a/src/components/phonenumber/PhoneNumber.unit.js +++ b/src/components/phonenumber/PhoneNumber.unit.js @@ -1,8 +1,10 @@ import Harness from '../../../test/harness'; import PhoneNumberComponent from './PhoneNumber'; +import assert from 'power-assert'; +import { Formio } from './../../Formio'; import { - comp1 + comp1, } from './fixtures'; describe('PhoneNumber Component', () => { @@ -11,4 +13,46 @@ describe('PhoneNumber Component', () => { Harness.testElements(component, 'input[type="text"]', 1); }); }); + + it('Should check mask and value in the phone component in the email template', (done) => { + const formJson = { + components: [{ + label: 'Phone Number', + tableView: true, + allowMultipleMasks: true, + inputMasks: [{ + label: 'mask1', + mask: 'mask1' + }], + key: 'phoneNumber', + type: 'phoneNumber', + input: true + }] + }; + const element = document.createElement('div'); + Formio.createForm(element, formJson) + .then(form => { + form.setSubmission({ + data: { + phoneNumber: { + value: 'mask1', + maskName: 'mask2' + } + }, + }); + + const phoneNumber = form.getComponent('phoneNumber'); + + setTimeout(() => { + assert.equal(phoneNumber.dataValue.value, 'mask1', 'Should check value'); + assert.equal(phoneNumber.dataValue.maskName, 'mask2', 'Should check maskName'); + const toString = phoneNumber.getValueAsString(phoneNumber.dataValue, { email: true }); + assert.ok(toString.includes('table'), 'Email template should render html table'); + assert.ok(toString.includes(phoneNumber.dataValue.maskName), 'Email template should have Phone Number mackName'); + assert.ok(toString.includes(phoneNumber.dataValue.value), 'Email template should have Phone Number value'); + done(); + }, 300); + }) + .catch(done); + }); }); diff --git a/src/components/textfield/TextField.js b/src/components/textfield/TextField.js index 2ffec2942a..d039b1e4da 100644 --- a/src/components/textfield/TextField.js +++ b/src/components/textfield/TextField.js @@ -2,6 +2,7 @@ import Input from '../_classes/input/Input'; import { conformToMask } from '@formio/vanilla-text-mask'; import * as FormioUtils from '../../utils/utils'; import NativePromise from 'native-promise-only'; +import _ from 'lodash'; export default class TextFieldComponent extends Input { static schema(...extend) { @@ -206,13 +207,6 @@ export default class TextFieldComponent extends Input { }; } - getValueAsString(value, options) { - if (value && this.component.inputFormat === 'plain' && /<[^<>]+>/g.test(value)) { - value = value.replaceAll('<','<').replaceAll('>', '>'); - } - return super.getValueAsString(value, options); - } - isHtmlRenderMode() { return super.isHtmlRenderMode() || ((this.options.readOnly || this.disabled) && @@ -252,4 +246,26 @@ export default class TextFieldComponent extends Input { this.dataValue = value; return NativePromise.resolve(value).then(() => super.beforeSubmit()); } + + getValueAsString(value, options) { + if (options?.email && this.visible && !this.skipInEmail && _.isObject(value)) { + const result = (` + + + + + + + +
${value.maskName}${value.value}
+ `); + + return result; + } + + if (value && this.component.inputFormat === 'plain' && /<[^<>]+>/g.test(value)) { + value = value.replaceAll('<','<').replaceAll('>', '>'); + } + return super.getValueAsString(value, options); + } } diff --git a/src/components/textfield/TextField.unit.js b/src/components/textfield/TextField.unit.js index 7b94a6e7dd..1e8bf643d7 100644 --- a/src/components/textfield/TextField.unit.js +++ b/src/components/textfield/TextField.unit.js @@ -40,6 +40,48 @@ describe('TextField Component', () => { }); }); + it('Should check mask and value in the textfield component in the email template', (done) => { + const formJson = { + components: [{ + label: 'Text Field', + tableView: true, + allowMultipleMasks: true, + inputMasks: [{ + label: 'mask1', + mask: 'mask1' + }], + key: 'textField', + type: 'textfield', + input: true + }] + }; + const element = document.createElement('div'); + Formio.createForm(element, formJson) + .then(form => { + form.setSubmission({ + data: { + textField: { + value: 'mask1', + maskName: 'mask2' + } + }, + }); + + const textField = form.getComponent('textField'); + + setTimeout(() => { + assert.equal(textField.dataValue.value, 'mask1', 'Should check value'); + assert.equal(textField.dataValue.maskName, 'mask2', 'Should check maskName'); + const toString = textField.getValueAsString(textField.dataValue, { email: true }); + assert.ok(toString.includes('table'), 'Email template should render html table'); + assert.ok(toString.includes(textField.dataValue.maskName), 'Email template should have Text Field mackName'); + assert.ok(toString.includes(textField.dataValue.value), 'Email template should have Text Field value'); + done(); + }, 300); + }) + .catch(done); + }); + it('Should provide required validation', () => { return Harness.testCreate(TextFieldComponent, _.merge({}, comp2, { validate: { required: true } diff --git a/src/components/tree/Tree.js b/src/components/tree/Tree.js index 0e30246a12..1cbd9aff82 100644 --- a/src/components/tree/Tree.js +++ b/src/components/tree/Tree.js @@ -473,6 +473,50 @@ export default class TreeComponent extends NestedDataComponent { ? this.treeRoot.getComponents() : super.getComponents(); } + + getValueAsString(value, options) { + const getChildAsString = (value) => { + let result = (` + + + `); + result += ` + + `; + result += Object.keys(value.data).map((k) => (` + + + + `; + + result += (` + +
${k} + ${value.data[k]} +
+ `)); + + if (value.children?.length !== 0) { + value.children?.forEach((v) => { + result += getChildAsString(v); + }); + } + + result += ` +
+ `); + + return result; + }; + + if (options?.email) { + let result = ''; + result += getChildAsString(value); + return result; + } + + return super.getValueAsString(value, options); + } } TreeComponent.prototype.hasChanged = Component.prototype.hasChanged; diff --git a/test/forms/formWithCheckboxRadioType.js b/test/forms/formWithCheckboxRadioType.js index 1ae05cee50..c3f8a42c2c 100644 --- a/test/forms/formWithCheckboxRadioType.js +++ b/test/forms/formWithCheckboxRadioType.js @@ -1,42 +1,42 @@ export default { - title: "test checkbox", - name: "testCheckbox", - path: "testcheckbox", - type: "form", - display: "form", - components: [ - { - label: "Checkbox 1", - inputType: "radio", - tableView: true, - defaultValue: false, - key: "checkbox1", - type: "checkbox", - name: "radio", - value: "value1", - input: true, - radio: false, - }, - { - label: "Checkbox 2", - inputType: "radio", - tableView: true, - defaultValue: false, - key: "checkbox2", - type: "checkbox", - name: "radio", - value: "value2", - input: true, - }, - { - label: "Checkbox", - tableView: false, - key: "checkbox", - type: "checkbox", - input: true, - } - ], - created: "2022-09-01T09:12:45.581Z", - modified: "2022-09-05T08:51:16.048Z", - machineName: "uubnbosxacwjzbk:testCheckbox", -}; + title: 'test checkbox', + name: 'testCheckbox', + path: 'testcheckbox', + type: 'form', + display: 'form', + components: [ + { + label: 'Checkbox 1', + inputType: 'radio', + tableView: true, + defaultValue: false, + key: 'checkbox1', + type: 'checkbox', + name: 'radio', + value: 'value1', + input: true, + radio: false, + }, + { + label: 'Checkbox 2', + inputType: 'radio', + tableView: true, + defaultValue: false, + key: 'checkbox2', + type: 'checkbox', + name: 'radio', + value: 'value2', + input: true, + }, + { + label: 'Checkbox', + tableView: false, + key: 'checkbox', + type: 'checkbox', + input: true, + } + ], + created: '2022-09-01T09:12:45.581Z', + modified: '2022-09-05T08:51:16.048Z', + machineName: 'uubnbosxacwjzbk:testCheckbox', + };