Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/components/Components.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import Component from './_classes/component/Component';
import EditFormUtils from './_classes/component/editForm/utils';
import BaseEditForm from './_classes/component/Component.form';
import _ from 'lodash';
import { isDataComponent } from '../utils';
export default class Components {
static _editFormUtils = EditFormUtils;

Expand Down Expand Up @@ -80,7 +81,8 @@ export default class Components {
else {
comp = new Component(component, options, data);
}
if (comp.path) {

if (comp.path && isDataComponent(comp.component)) {
comp.componentsMap[comp.path] = comp;
}
// Reset the componentMatches on the root element if any new component is created.
Expand Down
13 changes: 12 additions & 1 deletion src/utils/formUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,16 @@ const {
getItemTemplateKeys
} = Utils;

/**
* Checks if the component is expected to have data in submission object.
* @param {import('@formio/core').Component} component - The component to check.
* @returns {boolean} - TRUE if the component is a data component.
*/
function isDataComponent(component) {
const modelType = getModelType(component);
return modelType !== 'none' && modelType !== 'content';
}

export {
flattenComponents,
guid,
Expand Down Expand Up @@ -92,5 +102,6 @@ export {
isComponentDataEmpty,
isSelectResourceWithObjectValue,
compareSelectResourceWithObjectTypeValues,
getItemTemplateKeys
getItemTemplateKeys,
isDataComponent
};
90 changes: 90 additions & 0 deletions test/forms/testCustomValidationForContainerWithNestedLayoutComp.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
export default {
_id: '68ac2d19ca88b30e3544e46c',
title: 'Path example',
name: 'pathExample',
path: 'pathexample',
type: 'form',
display: 'form',
owner: '68ac2d7fca88b30e3544e83e',
components: [
{
label: 'Your contact details',
tableView: false,
validate: {
required: true,
custom:
'if (_.isEmpty(_.get(data,`${instance.path}.phone`)) && \n_.isEmpty(_.get(data,`${instance.path}.email`))) {\n valid=`One of either phone or email must be provided.`;\n}',
},
key: 'contact',
type: 'container',
input: true,
components: [
{
label: 'HTML',
attrs: [
{
attr: '',
value: '',
},
],
content: 'utuut',
refreshOnChange: false,
key: 'htmloooo',
type: 'htmlelement',
input: false,
tableView: false,
},
{
label: 'Panel',
collapsible: false,
key: 'panel',
type: 'panel',
input: false,
tableView: false,
components: [
{
label: 'Number',
applyMaskOn: 'change',
mask: false,
tableView: false,
delimiter: false,
requireDecimal: false,
inputFormat: 'plain',
truncateMultipleSpaces: false,
validateWhenHidden: false,
key: 'number',
type: 'number',
input: true,
},
],
},
{
label: 'Phone',
applyMaskOn: 'change',
tableView: true,
key: 'phone',
type: 'textfield',
input: true,
},
{
label: 'Email',
applyMaskOn: 'change',
tableView: true,
key: 'email',
type: 'email',
input: true,
},
],
},
{
label: 'Submit',
tableView: false,
key: 'submit',
type: 'button',
input: true,
saveOnEnter: false,
},
],
machineName: 'izutenexavvxnws:pathExample',
project: '67211a9aa929e4e6ebc2bf77',
};
16 changes: 15 additions & 1 deletion test/unit/Webform.unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ import formWithMergeComponentSchemaAndCustomLogic from '../forms/formWithMergeCo
import formWithServerValidation from '../forms/formWithServerValidation.js';
import formWithNumbers from '../forms/formWithNumbers.js';
import { wait } from '../util.js';
import testCustomValidationForContainerWithNestedLayoutComp from '../forms/testCustomValidationForContainerWithNestedLayoutComp.js';

const SpySanitize = sinon.spy(FormioUtils, 'sanitize');

Expand All @@ -108,7 +109,20 @@ if (_.has(Formio, 'Components.setComponents')) {
describe('Webform tests', function() {
this.retries(3);

it('Should show form validation errors if we insert invalid underscore data into a number component', async () => {
it('Should show validation errors on submit for container with layout components inside', (done) => {
Formio.createForm(document.createElement('div'), testCustomValidationForContainerWithNestedLayoutComp).then(form => {
assert.equal(!!form.visibleErrors.length, false);
form.submit();
setTimeout(() => {
assert.equal(form.errors.length, 1);
assert.equal(form.errors[0].message, 'One of either phone or email must be provided.');
assert.equal(!!form.visibleErrors.length, true);
done();
}, 400);
}).catch((err) => done(err));
});

it('Should show form validation errors if we insert invalid underscore data into a number component', async () => {
const form = await Formio.createForm(document.createElement('div'), formWithNumbers);
const numberDatagrid = form.getComponent('dataGrid.number');
const number = form.getComponent('number');
Expand Down
Loading