Skip to content

Commit

Permalink
FIO-8091: fixed missing metadata for html5 select component with defa…
Browse files Browse the repository at this point in the history
…ult value (#5579)
  • Loading branch information
roma-formio authored Apr 26, 2024
1 parent 86fde8f commit 65bf3d5
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 36 deletions.
96 changes: 61 additions & 35 deletions src/components/select/Select.js
Original file line number Diff line number Diff line change
Expand Up @@ -253,8 +253,12 @@ export default class SelectComponent extends ListComponent {
return super.shouldLoad;
}

get selectMetadata() {
return super.selectData;
}

get selectData() {
return this.component.selectData || super.selectData;
return this.component.selectData || this.selectMetadata;
}

isEntireObjectDisplay() {
Expand Down Expand Up @@ -1368,7 +1372,7 @@ export default class SelectComponent extends ListComponent {
return done;
}

normalizeSingleValue(value, retainObject) {
normalizeSingleValue(value) {
if (_.isNil(value)) {
return;
}
Expand All @@ -1377,35 +1381,6 @@ export default class SelectComponent extends ListComponent {
if (valueIsObject && Object.keys(value).length === 0) {
return value;
}
// Check to see if we need to save off the template data into our metadata.
if (retainObject) {
const templateValue = this.component.reference && value?._id ? value._id.toString() : value;
const shouldSaveData = !valueIsObject || this.component.reference;
if (templateValue && shouldSaveData && (this.templateData && this.templateData[templateValue]) && this.root?.submission) {
const submission = this.root.submission;
if (!submission.metadata) {
submission.metadata = {};
}
if (!submission.metadata.selectData) {
submission.metadata.selectData = {};
}

let templateData = this.templateData[templateValue];
if (this.component.multiple) {
templateData = {};
const dataValue = this.dataValue;
if (dataValue && _.isArray(dataValue) && dataValue.length) {
dataValue.forEach((dataValueItem) => {
const dataValueItemValue = this.component.reference ? dataValueItem._id.toString() : dataValueItem;
templateData[dataValueItemValue] = this.templateData[dataValueItemValue];
});
}
templateData[value] = this.templateData[value];
}

_.set(submission.metadata.selectData, this.path, templateData);
}
}

const dataType = this.component.dataType || 'auto';
const normalize = {
Expand Down Expand Up @@ -1472,18 +1447,69 @@ export default class SelectComponent extends ListComponent {
*/
normalizeValue(value) {
if (this.component.multiple && Array.isArray(value)) {
return value.map((singleValue) => this.normalizeSingleValue(singleValue, true));
return value.map((singleValue) => this.normalizeSingleValue(singleValue));
}

return super.normalizeValue(this.normalizeSingleValue(value));
}

setMetadata(value) {
if (_.isNil(value)) {
return;
}
const valueIsObject = _.isObject(value);
//check if value equals to default emptyValue
if (valueIsObject && Object.keys(value).length === 0) {
return value;
}
// Check to see if we need to save off the template data into our metadata.
const templateValue = this.component.reference && value?._id ? value._id.toString() : value;
const shouldSaveData = !valueIsObject || this.component.reference;
if (templateValue && shouldSaveData && this.templateData && this.templateData[templateValue] && this.root?.submission) {
const submission = this.root.submission;
if (!submission.metadata) {
submission.metadata = {};
}
if (!submission.metadata.selectData) {
submission.metadata.selectData = {};
}

let templateData = this.templateData[templateValue];
if (this.component.multiple) {
templateData = {};
const dataValue = this.dataValue;
if (dataValue && _.isArray(dataValue) && dataValue.length) {
dataValue.forEach((dataValueItem) => {
const dataValueItemValue = this.component.reference ? dataValueItem._id.toString() : dataValueItem;
templateData[dataValueItemValue] = this.templateData[dataValueItemValue];
});
}
templateData[value] = this.templateData[value];
}

return super.normalizeValue(this.normalizeSingleValue(value, true));
_.set(submission.metadata.selectData, this.path, templateData);
}
}

updateValue(value, flags) {
const changed = super.updateValue(value, flags);
if (changed || !this.selectMetadata) {
if (this.component.multiple && Array.isArray(this.dataValue)) {
this.dataValue.forEach(singleValue => this.setMetadata(singleValue));
}
else {
this.setMetadata(this.dataValue);
}
}
return changed;
}

setValue(value, flags = {}) {
const previousValue = this.dataValue;
const changed = this.updateValue(value, flags);
if (this.component.widget === 'html5' && (_.isEqual(value, previousValue) || _.isEqual(previousValue, {}) && _.isEqual(flags, {})) && !flags.fromSubmission ) {
return false;
}
const changed = this.updateValue(value, flags);
value = this.dataValue;
const hasPreviousValue = !this.isEmpty(previousValue);
const hasValue = !this.isEmpty(value);
Expand Down Expand Up @@ -1612,7 +1638,7 @@ export default class SelectComponent extends ListComponent {
if (values) {
if (_.isObject(value)) {
const compareComplexValues = (optionValue) => {
const normalizedOptionValue = this.normalizeSingleValue(optionValue, true);
const normalizedOptionValue = this.normalizeSingleValue(optionValue);

if (!_.isObject(normalizedOptionValue)) {
return false;
Expand Down
38 changes: 38 additions & 0 deletions src/components/select/Select.unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import {
comp19,
comp20,
comp21,
comp22,
} from './fixtures';

// eslint-disable-next-line max-statements
Expand Down Expand Up @@ -977,6 +978,43 @@ describe('Select Component', () => {
}).catch(done);
});

it('Should provide correct metadata.selectData for HTML5 Select with default value', (done) => {
const form = _.cloneDeep(comp22);
const element = document.createElement('div');

Formio.createForm(element, form).then(form => {
const submit = form.getComponent('submit');
const clickEvent = new Event('click');
const submitBtn = submit.refs.button;
submitBtn.dispatchEvent(clickEvent);

setTimeout(()=> {
const metadata = form.submission.metadata.selectData.select;
assert.equal(metadata.label, 'Label 1');
done();
}, 200);
}).catch(done);
});

it('Should provide correct metadata.selectData for ChoicesJS Select with default value', (done) => {
const form = _.cloneDeep(comp22);
form.components[0].widget='choicesjs';
const element = document.createElement('div');

Formio.createForm(element, form).then(form => {
const submit = form.getComponent('submit');
const clickEvent = new Event('click');
const submitBtn = submit.refs.button;
submitBtn.dispatchEvent(clickEvent);

setTimeout(()=> {
const metadata = form.submission.metadata.selectData.select;
assert.equal(metadata.label, 'Label 1');
done();
}, 200);
}).catch(done);
});

it('OnBlur validation should work properly with Select component', function(done) {
this.timeout(0);
const element = document.createElement('div');
Expand Down
41 changes: 41 additions & 0 deletions src/components/select/fixtures/comp22.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
export default {
title: 'FIO-8091',
name: 'fio8091',
path: 'fio8091',
type: 'form',
display: 'form',
components: [{
label: 'Select',
widget: 'choicesjs',
tableView: true,
dataSrc: 'url',
data: {
url: 'https://fake_url',
headers: [
{
key: '',
value: ''
},
],
},
valueProperty: 'value',
validateWhenHidden: false,
key: 'select',
type: 'select',
input: true,
defaultValue: 'value1',
selectValues: 'data',
disableLimit: false,
noRefreshOnScroll: false,
selectData: {
label: 'Label 1'
},
}, {
type: 'button',
label: 'Submit',
key: 'submit',
disableOnInvalid: true,
input: true,
tableView: false,
}],
};
3 changes: 2 additions & 1 deletion src/components/select/fixtures/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ import comp18 from './comp18';
import comp19 from './comp19';
import comp20 from './comp20';
import comp21 from './comp21';
export { comp1, comp2, comp4, comp5, comp6, comp7, comp8, comp9, comp10, comp11, comp12, comp13, comp14, comp15, comp16, comp17, comp18, comp19, comp20, comp21 };
import comp22 from './comp22';
export { comp1, comp2, comp4, comp5, comp6, comp7, comp8, comp9, comp10, comp11, comp12, comp13, comp14, comp15, comp16, comp17, comp18, comp19, comp20, comp21, comp22 };

0 comments on commit 65bf3d5

Please sign in to comment.