Skip to content

Commit

Permalink
FIO-4816: fixed email submission: data display issues (#4745)
Browse files Browse the repository at this point in the history
* FIO-4816: fixed email submission: data display issues

* corrected some points and added tetst

* FIO-4816: fixed tests

* fixed incorrect rebase issue

* fixed test

* fix test styles

---------

Co-authored-by: AlexanderLihodievskiy <alexandrel@form.io>
Co-authored-by: Travis Tidwell <travis@form.io>
Co-authored-by: TanyaGashtold <61136841+TanyaGashtold@users.noreply.github.com>
Co-authored-by: ICX\Tatsiana.Hashtold <tanya@form.io>
  • Loading branch information
5 people authored and lane-formio committed Sep 26, 2023
1 parent d55f406 commit be88864
Show file tree
Hide file tree
Showing 8 changed files with 267 additions and 50 deletions.
34 changes: 33 additions & 1 deletion src/components/form/Form.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
}
Expand All @@ -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 = (`
<table border="1" style="width:100%">
<tbody>
`);

this.everyComponent((component) => {
if (component.isInputComponent && component.visible && !component.skipInEmail) {
result += (`
<tr>
<th style="padding: 5px 10px;">${component.label}</th>
<td style="width:100%;padding:5px 10px;">${component.getView(component.dataValue, options)}</td>
</tr>
`);
}
}, {
...options,
fromRoot: true,
});

result += (`
</tbody>
</table>
`);

return result;
}
if (_.isEmpty(value)) {
return '';
}

return '[Complex Data]';
}

Expand Down
19 changes: 19 additions & 0 deletions src/components/form/Form.unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
20 changes: 20 additions & 0 deletions src/components/phonenumber/PhoneNumber.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import TextFieldComponent from '../textfield/TextField';
import _ from 'lodash';

export default class PhoneNumberComponent extends TextFieldComponent {
static schema(...extend) {
Expand Down Expand Up @@ -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 = (`
<table border="1" style="width:100%">
<tbody>
<tr>
<th style="padding: 5px 10px;">${value.maskName}</th>
<td style="width:100%;padding:5px 10px;">${value.value}</td>
</tr>
</tbody>
</table>
`);

return result;
}

return super.getValueAsString(value, options);
}
}
46 changes: 45 additions & 1 deletion src/components/phonenumber/PhoneNumber.unit.js
Original file line number Diff line number Diff line change
@@ -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', () => {
Expand All @@ -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);
});
});
30 changes: 23 additions & 7 deletions src/components/textfield/TextField.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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('<','&lt;').replaceAll('>', '&gt;');
}
return super.getValueAsString(value, options);
}

isHtmlRenderMode() {
return super.isHtmlRenderMode() ||
((this.options.readOnly || this.disabled) &&
Expand Down Expand Up @@ -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 = (`
<table border="1" style="width:100%">
<tbody>
<tr>
<th style="padding: 5px 10px;">${value.maskName}</th>
<td style="width:100%;padding:5px 10px;">${value.value}</td>
</tr>
</tbody>
</table>
`);

return result;
}

if (value && this.component.inputFormat === 'plain' && /<[^<>]+>/g.test(value)) {
value = value.replaceAll('<','&lt;').replaceAll('>', '&gt;');
}
return super.getValueAsString(value, options);
}
}
42 changes: 42 additions & 0 deletions src/components/textfield/TextField.unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand Down
44 changes: 44 additions & 0 deletions src/components/tree/Tree.js
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,50 @@ export default class TreeComponent extends NestedDataComponent {
? this.treeRoot.getComponents()
: super.getComponents();
}

getValueAsString(value, options) {
const getChildAsString = (value) => {
let result = (`
<table border="1" style="width:100%">
<tbody>
`);
result += `
<tr>
`;
result += Object.keys(value.data).map((k) => (`
<th style="padding: 5px 10px;">${k}</th>
<td style="width:100%;padding:5px 10px;">
${value.data[k]}
<br>
`));

if (value.children?.length !== 0) {
value.children?.forEach((v) => {
result += getChildAsString(v);
});
}

result += `
</td>
</tr>
`;

result += (`
</tbody>
</table>
`);

return result;
};

if (options?.email) {
let result = '';
result += getChildAsString(value);
return result;
}

return super.getValueAsString(value, options);
}
}

TreeComponent.prototype.hasChanged = Component.prototype.hasChanged;
82 changes: 41 additions & 41 deletions test/forms/formWithCheckboxRadioType.js
Original file line number Diff line number Diff line change
@@ -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',
};

0 comments on commit be88864

Please sign in to comment.