diff --git a/src/components/datagrid/DataGrid.js b/src/components/datagrid/DataGrid.js index ff269083d8..4772bab646 100644 --- a/src/components/datagrid/DataGrid.js +++ b/src/components/datagrid/DataGrid.js @@ -1,6 +1,6 @@ import _ from 'lodash'; import NestedArrayComponent from '../_classes/nestedarray/NestedArrayComponent'; -import { fastCloneDeep, getFocusableElements } from '../../utils/utils'; +import { fastCloneDeep, getFocusableElements, getComponent } from '../../utils/utils'; export default class DataGridComponent extends NestedArrayComponent { static schema(...extend) { @@ -578,6 +578,10 @@ export default class DataGridComponent extends NestedArrayComponent { options.row = `${rowIndex}-${colIndex}`; options.rowIndex = rowIndex; options.onChange = (flags, changed, modified) => { + if (changed.component.type === 'form') { + const formComp = getComponent(this.component.components, changed.component.key) + _.set(formComp, 'components', changed.component.components); + } this.triggerChange({ modified }); } diff --git a/test/unit/DataGrid.unit.js b/test/unit/DataGrid.unit.js index a4cd167122..7532795a24 100644 --- a/test/unit/DataGrid.unit.js +++ b/test/unit/DataGrid.unit.js @@ -27,7 +27,8 @@ import { withCollapsibleRowGroups, withAllowCalculateOverride, twoWithAllowCalculatedOverride, withCheckboxes, - withReorder + withReorder, + wizardWithDataGridWithNestedForm } from './fixtures/datagrid'; describe('DataGrid Component', () => { @@ -1083,3 +1084,65 @@ describe('SaveDraft functionality', () => { }).catch((err) => done(err)); }) }) + +describe('Wizard Form with Grid with Nested Form validation', () => { + const originalMakeRequest = Formio.makeRequest; + + const nestedForm = { + _id: '6800c965a969b07fbd8d7077', + title: 'Base Simple', + name: 'baseSimple', + path: 'basesimple', + type: 'form', + components: [ + { + label: 'First Name', + applyMaskOn: 'change', + tableView: true, + validate: { + required: true + }, + validateWhenHidden: false, + key: 'firstName', + type: 'textfield', + input: true + }, + { + label: 'Submit', + key: 'submit', + type: 'button' + } + ] + }; + + before(() => { + // Mock Formio.makeRequest to serve mock forms + Formio.makeRequest = (formio, type, url, method, data) => { + if (type === 'form' && method === 'get' && url.includes('6800c965a969b07fbd8d7077')) { + return Promise.resolve(_.cloneDeep(nestedForm)); + } + return Promise.resolve(); + }; + }); + + after(() => { + // Restore the original makeRequest + Formio.makeRequest = originalMakeRequest; + }); + + it('Should validate DataGrid with nested form before going to the next page', function (done) { + Formio.createForm(document.createElement('div'), wizardWithDataGridWithNestedForm) + .then((wizard) => { + const nextBtn = _.get(wizard.refs, `${wizard.wizardKey}-next`); + const clickEvent = new Event('click'); + nextBtn.dispatchEvent(clickEvent); + setTimeout(() => { + assert.equal(wizard.page, 0, 'Should open wizard page 1'); + const errors = wizard.errors; + assert.equal(errors.length, 1, 'Should have an error'); + assert.equal(errors[0].ruleName, 'required'); + done() + }, 300); + }).catch(done); + }); +}); diff --git a/test/unit/fixtures/datagrid/index.js b/test/unit/fixtures/datagrid/index.js index 9a856af3b5..4068d0a706 100644 --- a/test/unit/fixtures/datagrid/index.js +++ b/test/unit/fixtures/datagrid/index.js @@ -19,4 +19,5 @@ import withAllowCalculateOverride from './comp-with-allow-calculate-override'; import twoWithAllowCalculatedOverride from './two-comp-with-allow-calculate-override'; import withCheckboxes from './comp-with-checkboxes'; import withReorder from './comp-with-reorder'; -export { comp1, comp2, comp3, comp4, comp5, comp6, comp7, comp8, comp9, comp10, comp11, withCollapsibleRowGroups, withConditionalFieldsAndValidations, withDefValue, withLogic, withRowGroupsAndDefValue, modalWithRequiredFields, withAllowCalculateOverride, twoWithAllowCalculatedOverride, withCheckboxes, withReorder }; +import wizardWithDataGridWithNestedForm from './wizardWithDataGridWithNestedForm' +export { comp1, comp2, comp3, comp4, comp5, comp6, comp7, comp8, comp9, comp10, comp11, withCollapsibleRowGroups, withConditionalFieldsAndValidations, withDefValue, withLogic, withRowGroupsAndDefValue, modalWithRequiredFields, withAllowCalculateOverride, twoWithAllowCalculatedOverride, withCheckboxes, withReorder, wizardWithDataGridWithNestedForm }; diff --git a/test/unit/fixtures/datagrid/wizardWithDataGridWithNestedForm.js b/test/unit/fixtures/datagrid/wizardWithDataGridWithNestedForm.js new file mode 100644 index 0000000000..d483b7e6c4 --- /dev/null +++ b/test/unit/fixtures/datagrid/wizardWithDataGridWithNestedForm.js @@ -0,0 +1,68 @@ +export default { + _id: '68060aea27191cd69fda54a7', + type: 'form', + components: [ + { + title: 'Page 1', + breadcrumbClickable: true, + buttonSettings: { + previous: true, + cancel: true, + next: true + }, + navigateOnEnter: false, + saveOnEnter: false, + scrollToTop: false, + collapsible: false, + key: 'page1', + type: 'panel', + label: 'Page 1', + input: false, + tableView: false, + components: [ + { + label: 'Data Grid', + reorder: false, + addAnotherPosition: 'bottom', + layoutFixed: false, + enableRowGroups: false, + initEmpty: false, + tableView: false, + defaultValue: [{}], + validateWhenHidden: false, + key: 'dataGrid', + type: 'datagrid', + input: true, + components: [ + { + label: 'Form', + tableView: true, + form: '6800c965a969b07fbd8d7077', + useOriginalRevision: false, + reference: false, + key: 'form1', + type: 'form', + input: true, + lazyLoad: true + } + ] + } + ] + }, + { + title: 'Page 2', + label: 'Page 2', + type: 'panel', + key: 'page2', + input: false, + tableView: false, + components: [] + } + ], + revisions: '', + _vid: 0, + title: 'Wizard with dataGrid with nestedForm', + display: 'wizard', + name: 'dataGridWithNestedForm', + path: 'datagridwithnestedform' +};