Skip to content

Commit

Permalink
Merge pull request #5429 from formio/FIO-7514-fixed-simple-conditiona…
Browse files Browse the repository at this point in the history
…ls-for-select-resource-with-object-value

FIO-7514: fixed an isse where new simple conditionals do not work when condition is based on the value of resource select with object value
  • Loading branch information
brendanbond authored and lane-formio committed Dec 22, 2023
1 parent 65917af commit e3dc5a1
Show file tree
Hide file tree
Showing 10 changed files with 407 additions and 20 deletions.
89 changes: 89 additions & 0 deletions src/Webform.unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import {
formWithCollapsedPanel,
formWithCustomFormatDate,
tooltipActivateCheckbox,
formWithObjectValueSelect
} from '../test/formtest';
import UpdateErrorClassesWidgets from '../test/forms/updateErrorClasses-widgets';
import nestedModalWizard from '../test/forms/nestedModalWizard';
Expand Down Expand Up @@ -2697,6 +2698,94 @@ describe('Webform tests', function() {
}, 300);
}).catch((err) => done(err));
});

it('Should show field when condition is based on the values of select resource with object value', (done) => {
const element = document.createElement('div');
const values = [
{
_id: '656daabeebc67ecca1141569',
form: '656daab0ebc67ecca1141226',
data: {
number: 4,
notes: 'notes 4',
},
project: '656daa20ebc67ecca1140e8d',
state: 'submitted',
created: '2023-12-04T10:32:30.821Z',
modified: '2023-12-06T14:25:00.886Z',
},
{
_id: '656daabbebc67ecca11414a7',
form: '656daab0ebc67ecca1141226',
data: {
number: 3,
notes: 'notes 3',
},
project: '656daa20ebc67ecca1140e8d',
state: 'submitted',
created: '2023-12-04T10:32:27.322Z',
modified: '2023-12-06T14:25:07.494Z',
},
{
_id: '656daab8ebc67ecca11413e5',
form: '656daab0ebc67ecca1141226',
data: {
number: 2,
notes: 'notes 2',
},
project: '656daa20ebc67ecca1140e8d',
state: 'submitted',
created: '2023-12-04T10:32:24.514Z',
modified: '2023-12-06T14:25:13.610Z',
},
{
_id: '656daab5ebc67ecca1141322',
form: '656daab0ebc67ecca1141226',
data: {
number: 1,
notes: 'notes 1',
},
project: '656daa20ebc67ecca1140e8d',
state: 'submitted',
created: '2023-12-04T10:32:21.205Z',
modified: '2023-12-06T14:25:20.930Z',
},
];
const originalMakeRequest = Formio.makeRequest;
Formio.makeRequest = function() {
return new Promise(resolve => {
setTimeout(() => {
resolve(values);
}, 50);
});
};

Formio.createForm(element, formWithObjectValueSelect)
.then(form => {
const numberComp = form.getComponent('number');
assert.equal(numberComp.visible, false);

const selectRef = form.getComponent('selectRef');
selectRef.setValue(fastCloneDeep(values[3]));
const selectNoValuePropertyMult = form.getComponent('selectNoValueProperty');
selectNoValuePropertyMult.setValue([fastCloneDeep(values[2])]);
const selectEntireObject = form.getComponent('selectEntireObject');
selectEntireObject.setValue(fastCloneDeep(values[1].data));
const selectEntireObjectMult = form.getComponent('selectEntireObjectMult');
selectEntireObjectMult.setValue([fastCloneDeep(values[0].data)]);

setTimeout(() => {
assert.equal(numberComp.visible, true);
selectRef.setValue(fastCloneDeep(values[2]));
setTimeout(() => {
assert.equal(numberComp.visible, false);
Formio.makeRequest = originalMakeRequest;
done();
}, 400);
}, 400);
})
.catch(done);
});
});

describe('Calculate Value with allowed manual override', () => {
Expand Down
17 changes: 5 additions & 12 deletions src/components/_classes/list/ListComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import Field from '../field/Field';
import { GlobalFormio as Formio } from '../../../Formio';
import _ from 'lodash';
import NativePromise from 'native-promise-only';
import { getItemTemplateKeys } from '../../../utils/utils';

export default class ListComponent extends Field {
static schema(...extend) {
Expand Down Expand Up @@ -51,18 +52,10 @@ export default class ListComponent extends Field {
}

getTemplateKeys() {
this.templateKeys = [];
if (this.options.readOnly && this.component.template) {
const keys = this.component.template.match(/({{\s*(.*?)\s*}})/g);
if (keys) {
keys.forEach((key) => {
const propKey = key.match(/{{\s*item\.(.*?)\s*}}/);
if (propKey && propKey.length > 1) {
this.templateKeys.push(propKey[1]);
}
});
}
}
const template = this.component.template;
this.templateKeys = this.options.readOnly && template
? getItemTemplateKeys(template)
: [];
}

get requestHeaders() {
Expand Down
18 changes: 16 additions & 2 deletions src/components/select/Select.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { GlobalFormio as Formio } from '../../Formio';
import ListComponent from '../_classes/list/ListComponent';
import Form from '../../Form';
import NativePromise from 'native-promise-only';
import { getRandomComponentId, boolValue, isPromise, componentValueTypes, getComponentSavedTypes, unescapeHTML } from '../../utils/utils';
import { getRandomComponentId, boolValue, isPromise, componentValueTypes, getComponentSavedTypes, unescapeHTML, isSelectResourceWithObjectValue } from '../../utils/utils';

let Choices;
if (typeof window !== 'undefined') {
Expand Down Expand Up @@ -69,7 +69,21 @@ export default class SelectComponent extends ListComponent {
return {
...super.conditionOperatorsSettings,
valueComponent(classComp) {
return { ... classComp, type: 'select' };
const valueComp = { ... classComp, type: 'select' };

if (isSelectResourceWithObjectValue(classComp)) {
valueComp.reference = false;
valueComp.onSetItems = `
var templateKeys = utils.getItemTemplateKeys(component.template) || [];
items = _.map(items || [], i => {
var item = {};
_.each(templateKeys, k => _.set(item, k, _.get(i, k)));
return item;
})
`;
}

return valueComp;
}
};
}
Expand Down
26 changes: 25 additions & 1 deletion src/utils/conditionOperators/IsEqualTo.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import ConditionOperator from './ConditionOperator';
import _ from 'lodash';
import { getItemTemplateKeys, isSelectResourceWithObjectValue } from '../utils';

export default class IsEqualTo extends ConditionOperator {
static get operatorKey() {
Expand All @@ -10,7 +11,7 @@ export default class IsEqualTo extends ConditionOperator {
return 'Is Equal To';
}

execute({ value, comparedValue }) {
execute({ value, comparedValue, instance, conditionComponentPath }) {
if (value && comparedValue && typeof value !== typeof comparedValue && _.isString(comparedValue)) {
try {
comparedValue = JSON.parse(comparedValue);
Expand All @@ -19,6 +20,29 @@ export default class IsEqualTo extends ConditionOperator {
catch (e) {}
}

if (instance && instance.root) {
const conditionTriggerComponent = instance.root.getComponent(conditionComponentPath);

if (
conditionTriggerComponent
&& isSelectResourceWithObjectValue(conditionTriggerComponent.component)
&& conditionTriggerComponent.component?.template
) {
if (!value || !_.isPlainObject(value)) {
return false;
}

const { template, valueProperty } = conditionTriggerComponent.component;

if (valueProperty === 'data') {
value = { data: value };
comparedValue = { data: comparedValue };
}

return _.every(getItemTemplateKeys(template) || [], k => _.isEqual(_.get(value, k), _.get(comparedValue, k)));
}
}

//special check for select boxes
if (_.isObject(value) && comparedValue && _.isString(comparedValue)) {
return value[comparedValue];
Expand Down
9 changes: 4 additions & 5 deletions src/utils/conditionOperators/IsNotEqualTo.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import ConditionOperator from './ConditionOperator';
import _ from 'lodash';
import IsEqualTo from './IsEqualTo';

export default class IsNotEqualTo extends ConditionOperator {
export default class IsNotEqualTo extends IsEqualTo {
static get operatorKey() {
return 'isNotEqual';
}
Expand All @@ -10,7 +9,7 @@ export default class IsNotEqualTo extends ConditionOperator {
return 'Is Not Equal To';
}

execute({ value, comparedValue }) {
return !_.isEqual(value, comparedValue);
execute(options) {
return !super.execute(options);
}
}
24 changes: 24 additions & 0 deletions src/utils/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -1570,3 +1570,27 @@ export function getComponentSavedTypes(fullSchema) {

return null;
}

export function getItemTemplateKeys(template) {
const templateKeys = [];
if (!template) {
return templateKeys;
}
const keys = template.match(/({{\s*(.*?)\s*}})/g);

if (keys) {
keys.forEach((key) => {
const propKey = key.match(/{{\s*item\.(.*?)\s*}}/);
if (propKey && propKey.length > 1) {
templateKeys.push(propKey[1]);
}
});
}

return templateKeys;
}

export function isSelectResourceWithObjectValue(comp = {}) {
const { reference, dataSrc, valueProperty } = comp;
return reference || (dataSrc === 'resource' && (!valueProperty || valueProperty === 'data'));
}
Loading

0 comments on commit e3dc5a1

Please sign in to comment.