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 += (`
+
+ ${component.label} |
+ ${component.getView(component.dataValue, options)} |
+
+ `);
+ }
+ }, {
+ ...options,
+ fromRoot: true,
+ });
+
+ result += (`
+
+
+ `);
+
+ 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) => (`
+ ${k} |
+
+ ${value.data[k]}
+
+ `));
+
+ if (value.children?.length !== 0) {
+ value.children?.forEach((v) => {
+ result += getChildAsString(v);
+ });
+ }
+
+ result += `
+ |
+
+ `;
+
+ 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',
+ };