fix(form-core): do a deep equal check for choice group modelValue setter

This commit is contained in:
Joren Broekema 2021-02-22 13:12:47 +01:00
parent 72ebd75cfa
commit d0b37e626c
3 changed files with 51 additions and 3 deletions

View file

@ -0,0 +1,5 @@
---
'@lion/form-core': patch
---
Do a deep equals check for choice group children that have complex modelValues, enabling modelValue setter to work on the group level.

View file

@ -44,7 +44,12 @@ const ChoiceGroupMixinImplementation = superclass =>
* @param {ChoiceInputHost} el
* @param {any} val
*/
const checkCondition = (el, val) => el.choiceValue === val;
const checkCondition = (el, val) => {
if (typeof el.choiceValue === 'object') {
return JSON.stringify(el.choiceValue) === JSON.stringify(value);
}
return el.choiceValue === val;
};
if (this.__isInitialModelValue) {
this.__isInitialModelValue = false;
@ -281,7 +286,16 @@ const ChoiceGroupMixinImplementation = superclass =>
_setCheckedElements(value, check) {
for (let i = 0; i < this.formElements.length; i += 1) {
if (this.multipleChoice) {
this.formElements[i].checked = value.includes(this.formElements[i].value);
let valueIsIncluded = value.includes(this.formElements[i].modelValue.value);
// For complex values, do a JSON Stringified includes check, because [{ v: 'foo'}].includes({ v: 'foo' }) => false
if (typeof this.formElements[i].modelValue.value === 'object') {
valueIsIncluded = /** @type {any[]} */ (value)
.map(/** @param {Object} v */ v => JSON.stringify(v))
.includes(JSON.stringify(this.formElements[i].modelValue.value));
}
this.formElements[i].checked = valueIsIncluded;
} else if (check(this.formElements[i], value)) {
// Allows checking against custom values e.g. formattedValue or serializedValue
this.formElements[i].checked = true;

View file

@ -286,7 +286,7 @@ export function runChoiceGroupMixinSuite({ parentTagString, childTagString, choi
}
});
it('can check a radio by supplying an available modelValue', async () => {
it('can check a choice by supplying an available modelValue', async () => {
const el = /** @type {ChoiceInputGroup} */ (await fixture(html`
<${parentTag} name="gender[]">
<${childTag}
@ -310,6 +310,35 @@ export function runChoiceGroupMixinSuite({ parentTagString, childTagString, choi
expect(el.formElements[2].checked).to.be.true;
});
it('can check a choice by supplying an available modelValue even if this modelValue is an array or object', async () => {
const el = /** @type {ChoiceInputGroup} */ (await fixture(html`
<${parentTag} name="gender[]">
<${childTag}
.modelValue="${{ value: { v: 'male' }, checked: false }}"
></${childTag}>
<${childTag}
.modelValue="${{ value: { v: 'female' }, checked: true }}"
></${childTag}>
<${childTag}
.modelValue="${{ value: { v: 'other' }, checked: false }}"
></${childTag}>
</${parentTag}>
`));
if (cfg.choiceType === 'single') {
expect(el.modelValue).to.eql({ v: 'female' });
} else {
expect(el.modelValue).to.deep.equal([{ v: 'female' }]);
}
if (cfg.choiceType === 'single') {
el.modelValue = { v: 'other' };
} else {
el.modelValue = [{ v: 'other' }];
}
expect(el.formElements[2].checked).to.be.true;
});
it('expect child nodes to only fire one model-value-changed event per instance', async () => {
let counter = 0;
const el = /** @type {ChoiceInputGroup} */ (await fixture(html`