Skip to content

Commit

Permalink
FIO-9385 Preserve non-default widget settings after evaluating field …
Browse files Browse the repository at this point in the history
…logic

- originalComponent in Component.js did not capture non-default widget settings since they were added after component initialization
- During field logic evaluation, the component was falling back to originalComponent and not preserving the widget settings
- Update originalComponent after applying widget settings in TextField and DateTime to maintain them after field logic eval
  • Loading branch information
blakekrammes committed Dec 17, 2024
1 parent 0d6767f commit 0adf189
Show file tree
Hide file tree
Showing 8 changed files with 146 additions and 4 deletions.
6 changes: 5 additions & 1 deletion src/components/datetime/DateTime.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import _ from 'lodash';
import moment from 'moment';
import FormioUtils from '../../utils';
import { componentValueTypes, getComponentSavedTypes } from '../../utils/utils';
import { componentValueTypes, fastCloneDeep, getComponentSavedTypes } from '../../utils/utils';
import Input from '../_classes/input/Input';

export default class DateTimeComponent extends Input {
Expand Down Expand Up @@ -139,6 +139,10 @@ export default class DateTimeComponent extends Input {
maxDate: _.get(this.component, 'datePicker.maxDate'),
...customOptions,
};
// update originalComponent to include widget and other updated settings
// it is done here since these settings depend on properties present after the component is initialized
// originalComponent is used to restore the component (and widget) after evaluating field logic
this.originalComponent = fastCloneDeep(this.component);
/* eslint-enable camelcase */
}

Expand Down
3 changes: 3 additions & 0 deletions src/components/textfield/TextField.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,9 @@ export default class TextFieldComponent extends Input {
locale: this.component.widget.locale || this.options.language,
saveAs: 'text'
};
// update originalComponent to include widget settings after component initialization
// originalComponent is used to restore the component (and widget) after evaluating field logic
this.originalComponent = FormioUtils.fastCloneDeep(this.component);
}
}

Expand Down
11 changes: 10 additions & 1 deletion test/unit/DateTime.unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ import {
comp11,
comp12,
comp13,
comp14
comp14,
requiredFieldLogicComp,
} from './fixtures/datetime';

describe('DateTime Component', () => {
Expand Down Expand Up @@ -771,6 +772,14 @@ describe('DateTime Component', () => {
})
});

it('Should preserve the calendar widget settings after field logic is evaluated', async () => {
// see https://formio.atlassian.net/browse/FIO-9385
// emulate viewing a submission in the portal with { readOnly: true }
const form = await Formio.createForm(document.createElement('div'), requiredFieldLogicComp, { readOnly: true });
const dateTimeComponent = form.getComponent('dateTime');
assert.equal(dateTimeComponent.widget.settings.readOnly, true);
});

// it('Should provide correct date in selected timezone after submission', (done) => {
// const form = _.cloneDeep(comp9);
// const element = document.createElement('div');
Expand Down
9 changes: 9 additions & 0 deletions test/unit/TextField.unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
comp6,
withDisplayAndInputMasks,
comp7,
requiredFieldLogicComp,
} from './fixtures/textfield';

import { comp10 as formWithCalendarTextField } from './fixtures/datetime';
Expand Down Expand Up @@ -1379,6 +1380,14 @@ describe('TextField Component', () => {
}).catch(done);
});

it('Should preserve the calendar widget settings after field logic is evaluated', async () => {
// see https://formio.atlassian.net/browse/FIO-9385
// emulate viewing a submission in the portal with { readOnly: true }
const form = await Formio.createForm(document.createElement('div'), requiredFieldLogicComp, { readOnly: true });
const textFieldComponent = form.getComponent('textField');
assert.equal(textFieldComponent.widget.settings.readOnly, true);
});

it('Test Display mask', (done) => {
const element = document.createElement('div');

Expand Down
3 changes: 2 additions & 1 deletion test/unit/fixtures/datetime/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ import comp11 from './comp11';
import comp12 from './comp12';
import comp13 from './comp13';
import comp14 from './comp14';
export { comp1, comp2, comp3, comp5, comp6, comp7, comp8, comp9, comp10, comp11, comp12, comp13, comp14 };
import requiredFieldLogicComp from './requiredFieldLogicComp';
export { comp1, comp2, comp3, comp5, comp6, comp7, comp8, comp9, comp10, comp11, comp12, comp13, comp14, requiredFieldLogicComp };
62 changes: 62 additions & 0 deletions test/unit/fixtures/datetime/requiredFieldLogicComp.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
export default {
components: [
{
"label": "dateTime",
"displayInTimezone": "submission",
"format": "MM/dd/yyyy:HH:mm:ss",
"tableView": false,
"datePicker": {
"disableWeekends": false,
"disableWeekdays": false
},
"timePicker": {
"showMeridian": false
},
"enableMinDateInput": false,
"enableMaxDateInput": false,
"validateWhenHidden": false,
"key": "dateTime",
"logic": [
{
"name": "requiredLogic",
"trigger": {
"type": "javascript",
"javascript": "result = true;"
},
"actions": [
{
"name": "setRequired",
"type": "property",
"property": {
"label": "Required",
"value": "validate.required",
"type": "boolean"
},
"state": true
}
]
}
],
"type": "datetime",
"input": true,
"widget": {
"type": "calendar",
"displayInTimezone": "submission",
"locale": "en",
"useLocaleSettings": false,
"allowInput": true,
"mode": "single",
"enableTime": true,
"noCalendar": false,
"format": "MM/dd/yyyy:HH:mm:ss",
"hourIncrement": 1,
"minuteIncrement": 1,
"time_24hr": true,
"minDate": null,
"disableWeekends": false,
"disableWeekdays": false,
"maxDate": null
}
}
]
}
3 changes: 2 additions & 1 deletion test/unit/fixtures/textfield/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ import comp5 from './comp5';
import comp6 from './comp6';
import withDisplayAndInputMasks from './comp-with-display-and-value-masks';
import comp7 from './comp7';
export { comp1, comp2, comp3, comp4, comp5, comp6, comp7, withDisplayAndInputMasks };
import requiredFieldLogicComp from './requiredFieldLogicComp';
export { comp1, comp2, comp3, comp4, comp5, comp6, comp7, withDisplayAndInputMasks, requiredFieldLogicComp };
53 changes: 53 additions & 0 deletions test/unit/fixtures/textfield/requiredFieldLogicComp.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
export default {
components: [
{
"label": "Text Field",
"widget": {
"type": "calendar",
"altInput": true,
"allowInput": true,
"clickOpens": true,
"enableDate": true,
"enableTime": true,
"mode": "single",
"noCalendar": false,
"format": "MM/dd/yyyy:HH:mm:ss",
"dateFormat": "MM/dd/yyyy:HH:mm:ss",
"useLocaleSettings": false,
"hourIncrement": 1,
"minuteIncrement": 5,
"time_24hr": false,
"saveAs": "text",
"displayInTimezone": "viewer",
"locale": "en"
},
"applyMaskOn": "change",
"tableView": true,
"validateWhenHidden": false,
"key": "textField",
"logic": [
{
"name": "requiredLogic",
"trigger": {
"type": "javascript",
"javascript": "result = true;"
},
"actions": [
{
"name": "setRequired",
"type": "property",
"property": {
"label": "Required",
"value": "validate.required",
"type": "boolean"
},
"state": true
}
]
}
],
"type": "textfield",
"input": true
}
]
}

0 comments on commit 0adf189

Please sign in to comment.