diff --git a/src/components/_classes/component/Component.js b/src/components/_classes/component/Component.js index 0758cb15f9..29fc99076a 100644 --- a/src/components/_classes/component/Component.js +++ b/src/components/_classes/component/Component.js @@ -3388,14 +3388,12 @@ export default class Component extends Element { if (flags.silentCheck) { return []; } + let isDirty = this.dirty || flags.dirty; if (this.options.alwaysDirty) { - flags.dirty = true; + isDirty = true; } - if (flags.fromSubmission && this.hasValue(data)) { - flags.dirty = this.pristine && this.component.protected ? false : true; - } - this.setDirty(flags.dirty); - return this.setComponentValidity(errors, flags.dirty, flags.silentCheck, flags.fromSubmission); + this.setDirty(isDirty); + return this.setComponentValidity(errors, isDirty, flags.silentCheck, flags.fromSubmission); } /** diff --git a/src/components/editgrid/EditGrid.js b/src/components/editgrid/EditGrid.js index b635634018..f6e1daba7a 100644 --- a/src/components/editgrid/EditGrid.js +++ b/src/components/editgrid/EditGrid.js @@ -1163,17 +1163,18 @@ export default class EditGridComponent extends NestedArrayComponent { this.root?.submitted; } - shouldValidateRow(editRow, dirty) { + shouldValidateRow(editRow, dirty, fromSubmission) { return this.shouldValidateDraft(editRow) || editRow.state === EditRowState.Saving || editRow.state === EditRowState.Editing || editRow.alerts || + fromSubmission || dirty; } - validateRow(editRow, dirty, forceSilentCheck) { + validateRow(editRow, dirty, forceSilentCheck, fromSubmission) { editRow.errors = []; - if (this.shouldValidateRow(editRow, dirty)) { + if (this.shouldValidateRow(editRow, dirty, fromSubmission)) { const silentCheck = (this.component.rowDrafts && !this.shouldValidateDraft(editRow)) || forceSilentCheck; const rootValue = fastCloneDeep(this.rootValue); const editGridValue = _.get(rootValue, this.path, []); @@ -1250,7 +1251,7 @@ export default class EditGridComponent extends NestedArrayComponent { } checkComponentValidity(data, dirty, row, options = {}, errors = []) { - const { silentCheck } = options; + const { silentCheck, fromSubmission } = options; const superValid = super.checkComponentValidity(data, dirty, row, options, errors); // If super tells us that component invalid and there is no need to update alerts, just return false @@ -1262,7 +1263,7 @@ export default class EditGridComponent extends NestedArrayComponent { const allRowErrors = []; this.editRows.forEach((editRow, index) => { // Trigger all errors on the row. - const rowErrors = this.validateRow(editRow, dirty, silentCheck); + const rowErrors = this.validateRow(editRow, dirty, silentCheck, fromSubmission); errors.push(...rowErrors); allRowErrors.push(...rowErrors); diff --git a/test/unit/Component.unit.js b/test/unit/Component.unit.js index 970b4cf85b..a4ed655cf8 100644 --- a/test/unit/Component.unit.js +++ b/test/unit/Component.unit.js @@ -311,6 +311,10 @@ describe('Component', () => { type: 'email', input: true }, + { + type: 'button', + key: 'submit' + } ], }; @@ -326,6 +330,8 @@ describe('Component', () => { }); }) .then(() => { + const submitButton = form.getComponent('submit'); + submitButton.refs.button.click(); setTimeout(() => { const email = form.getComponent('email'); expect(email.refs.input[0].classList.contains('is-invalid')).to.be.false; diff --git a/test/unit/EditGrid.unit.js b/test/unit/EditGrid.unit.js index 2ae3475f5a..5a0a2191a1 100644 --- a/test/unit/EditGrid.unit.js +++ b/test/unit/EditGrid.unit.js @@ -716,12 +716,12 @@ describe('EditGrid Component', () => { assert(form.submitted, 'Form should be submitted'); const editRow = editGrid.editRows[0]; assert(editRow.alerts, 'Should add an error alert to the modal'); - assert.equal(editRow.errors.length, 2, 'Should add errors to components inside draft row aftre it was submitted'); + assert.equal(editRow.errors.length, 2, 'Should add errors to components inside draft row after it was submitted'); const textField = editRow.components[0].getComponent('textField'); const alert = editGrid.alert; assert(alert, 'Should show an error alert when drafts are enabled and form is submitted'); - assert(textField.element.className.includes('has-error'), 'Should add error class to component even when drafts enabled if the form was submitted'); + assert(textField.element.className.includes('error'), 'Should add error class to component even when drafts enabled if the form was submitted'); // 4. Change the value of the text field textField.setValue('new value', { modified: true }); @@ -729,7 +729,7 @@ describe('EditGrid Component', () => { setTimeout(() => { const textFieldEl = textField.element; assert.equal(textField.dataValue, 'new value'); - assert(!textFieldEl.className.includes('has-error'), 'Should remove an error class from component when it was fixed'); + assert(!textFieldEl.className.includes('error'), 'Should remove an error class from component when it was fixed'); const editRow = editGrid.editRows[0]; const textField2 = editRow.components[0].getComponent('textField2'); diff --git a/test/unit/SelectBoxes.unit.js b/test/unit/SelectBoxes.unit.js index 01bef90f58..8cc2f2deb8 100644 --- a/test/unit/SelectBoxes.unit.js +++ b/test/unit/SelectBoxes.unit.js @@ -117,6 +117,10 @@ describe('SelectBoxes Component', () => { validate: { minSelectedCount: 2 } + }, + { + type: 'button', + key: 'submit' } ] }; @@ -129,6 +133,8 @@ describe('SelectBoxes Component', () => { } }; const comp = form.getComponent('options'); + const submitButton = form.getComponent('submit'); + submitButton.refs.button.click(); setTimeout(() => { const { messageContainer } = comp.refs; assert.equal( @@ -155,6 +161,10 @@ describe('SelectBoxes Component', () => { minSelectedCount: 2, }, minSelectedCountMessage: 'Please select at least {{minCount}} items.' + }, + { + type: 'button', + key: 'submit' } ] }; @@ -167,6 +177,8 @@ describe('SelectBoxes Component', () => { } }; const comp = form.getComponent('options'); + const submitButton = form.getComponent('submit'); + submitButton.refs.button.click(); setTimeout(() => { const { messageContainer } = comp.refs; assert.equal( @@ -209,6 +221,10 @@ describe('SelectBoxes Component', () => { validate: { maxSelectedCount: 2 } + }, + { + type: 'button', + key: 'submit' } ] }; @@ -221,6 +237,8 @@ describe('SelectBoxes Component', () => { } }; const comp = form.getComponent('options'); + const submitButton = form.getComponent('submit'); + submitButton.refs.button.click(); setTimeout(() => { const { messageContainer } = comp.refs; assert.equal( @@ -247,6 +265,10 @@ describe('SelectBoxes Component', () => { maxSelectedCount: 2, }, maxSelectedCountMessage: 'Please select {{maxCount}} items at most.' + }, + { + type: 'button', + key: 'submit' } ] }; @@ -259,6 +281,8 @@ describe('SelectBoxes Component', () => { } }; const comp = form.getComponent('options'); + const submitButton = form.getComponent('submit'); + submitButton.refs.button.click(); setTimeout(() => { const { messageContainer } = comp.refs; assert.equal( diff --git a/test/unit/TextField.unit.js b/test/unit/TextField.unit.js index e143a39f04..5016e3b0b2 100644 --- a/test/unit/TextField.unit.js +++ b/test/unit/TextField.unit.js @@ -187,7 +187,11 @@ describe('TextField Component', () => { key: 'textField', type: 'textfield', input: true - }] + }, + { + type: 'button', + key: 'submit' + }] }; const element = document.createElement('div'); Formio.createForm(element, formJson) @@ -198,6 +202,8 @@ describe('TextField Component', () => { } }; const textField = form.getComponent('textField'); + const sumbitButton = form.getComponent('submit'); + sumbitButton.refs.button.click(); setTimeout(() => { assert.equal(textField.refs.messageContainer.children.length, 1); assert.equal(textField.refs.messageContainer.children[0].innerHTML, 'Custom Error Message'); diff --git a/test/unit/Webform.unit.js b/test/unit/Webform.unit.js index 911136ca21..c67beebed3 100644 --- a/test/unit/Webform.unit.js +++ b/test/unit/Webform.unit.js @@ -2304,7 +2304,7 @@ describe('Webform tests', function() { }); }); - it('Should show errors on setSubmission when providing explicit data values.', (done) => { + it('Should not show errors on setSubmission when providing explicit data values.', (done) => { formElement.innerHTML = ''; const form = new Webform(formElement,{ language: 'en' }); form.setForm( @@ -2330,12 +2330,17 @@ describe('Webform tests', function() { }], } ).then(() => { - checkForErrors(form, {}, { - data:{ + form.setSubmission({ + data: { number: 2, textArea: '' } - }, 2, done); + }); + setTimeout(() => { + assert.equal(form.errors.length, 2); + assert.equal(form.visibleErrors.length, 0); + done(); + },200); }); }); @@ -5186,7 +5191,7 @@ describe('Webform tests', function() { form.setForm(formWithCheckboxRadioTypeAndValidation).then(() => { const submitButton = form.getComponent('submit'); assert.ok(submitButton.disabled, 'Submit button should be disabled'); - const errors = form.validate(); + const errors = form.validate(); assert.strictEqual(errors.length, 1, 'Should return 1 error for the checkbox'); assert.strictEqual(errors[0].component.label, 'Checkbox 1', 'The error should be for the checkbox component'); assert.strictEqual(errors[0].errorKeyOrMessage, 'required', 'Should show required validation error'); diff --git a/test/unit/Wizard.unit.js b/test/unit/Wizard.unit.js index 9f1d328cdc..51bddf1548 100644 --- a/test/unit/Wizard.unit.js +++ b/test/unit/Wizard.unit.js @@ -637,7 +637,7 @@ describe('Wizard tests', () => { }; clickWizardBtn('link[4]'); - + setTimeout(() => { checkPage(4); clickWizardBtn('submit'); @@ -664,7 +664,7 @@ describe('Wizard tests', () => { }) .catch((err) => done(err)); }); - + it('Should execute advanced logic for wizard pages', function(done) { const formElement = document.createElement('div'); @@ -1178,7 +1178,7 @@ describe('Wizard tests', () => { assert.equal(wizard.visibleErrors.length, 3, 'Should have page validation error'); assert.equal(wizard.refs.errorRef.length, 3, 'Should keep alert with validation errors'); - checkInvalidComp('textField'); + checkInvalidComp('textField', true); clickWizardBtn('errorRef[1]', true); setTimeout(() => { @@ -1186,7 +1186,7 @@ describe('Wizard tests', () => { assert.equal(wizard.visibleErrors.length, 3, 'Should have page validation error'); assert.equal(wizard.refs.errorRef.length, 3, 'Should keep alert with validation errors'); - checkInvalidComp('checkbox'); + checkInvalidComp('checkbox', true); wizard.getComponent('checkbox').setValue(true); setTimeout(() => {