fix(form-core): choice-group initialization values + null support

This commit is contained in:
Thijs Louisse 2021-04-06 12:44:42 +02:00
parent 97b8592cd9
commit 181a1d452b
4 changed files with 83 additions and 5 deletions

View file

@ -0,0 +1,6 @@
---
'@lion/form-core': patch
---
- form-core: pending initialization values in order of execution
- form-core: choiceGroup null and undefined values support

View file

@ -53,8 +53,8 @@ const ChoiceGroupMixinImplementation = superclass =>
};
if (this.__isInitialModelValue) {
this.__isInitialModelValue = false;
this.registrationComplete.then(() => {
this.__isInitialModelValue = false;
this._setCheckedElements(value, checkCondition);
this.requestUpdate('modelValue', this.__oldModelValue);
});
@ -89,8 +89,8 @@ const ChoiceGroupMixinImplementation = superclass =>
const checkCondition = (el, val) => el.serializedValue.value === val;
if (this.__isInitialSerializedValue) {
this.__isInitialSerializedValue = false;
this.registrationComplete.then(() => {
this.__isInitialSerializedValue = false;
this._setCheckedElements(value, checkCondition);
this.requestUpdate('serializedValue');
});
@ -116,8 +116,8 @@ const ChoiceGroupMixinImplementation = superclass =>
const checkCondition = (el, val) => el.formattedValue === val;
if (this.__isInitialFormattedValue) {
this.__isInitialFormattedValue = false;
this.registrationComplete.then(() => {
this.__isInitialFormattedValue = false;
this._setCheckedElements(value, checkCondition);
});
} else {
@ -307,6 +307,12 @@ const ChoiceGroupMixinImplementation = superclass =>
* @protected
*/
_setCheckedElements(value, check) {
if (value === null || value === undefined) {
// Uncheck all
// eslint-disable-next-line no-return-assign, no-param-reassign
this.formElements.forEach(fe => (fe.checked = false));
return;
}
for (let i = 0; i < this.formElements.length; i += 1) {
if (this.multipleChoice) {
let valueIsIncluded = value.includes(this.formElements[i].modelValue.value);

View file

@ -2,7 +2,7 @@ import { LitElement } from '@lion/core';
import { LionInput } from '@lion/input';
import '@lion/fieldset/define';
import { FormGroupMixin, Required } from '@lion/form-core';
import { expect, html, fixture, unsafeStatic } from '@open-wc/testing';
import { expect, html, fixture, fixtureSync, unsafeStatic } from '@open-wc/testing';
import { ChoiceGroupMixin } from '../../src/choice-group/ChoiceGroupMixin.js';
import { ChoiceInputMixin } from '../../src/choice-group/ChoiceInputMixin.js';
@ -246,6 +246,72 @@ export function runChoiceGroupMixinSuite({ parentTagString, childTagString, choi
expect(el.formElements[2].checked).to.be.true;
});
it('correctly handles modelValue being set before registrationComplete', async () => {
const el = /** @type {ChoiceInputGroup} */ (fixtureSync(html`
<${parentTag} name="gender[]" .modelValue=${null}>
<${childTag} .choiceValue=${'male'}></${childTag}>
<${childTag} .choiceValue=${'female'}></${childTag}>
<${childTag} .choiceValue=${'other'}></${childTag}>
</${parentTag}>
`));
if (cfg.choiceType === 'single') {
el.modelValue = 'other';
await el.registrationComplete;
expect(el.modelValue).to.equal('other');
} else {
el.modelValue = ['other'];
await el.registrationComplete;
expect(el.modelValue).to.deep.equal(['other']);
}
});
it('correctly handles serializedValue being set before registrationComplete', async () => {
const el = /** @type {ChoiceInputGroup} */ (fixtureSync(html`
<${parentTag} name="gender[]" .serializedValue=${null}>
<${childTag} .choiceValue=${'male'}></${childTag}>
<${childTag} .choiceValue=${'female'}></${childTag}>
<${childTag} .choiceValue=${'other'}></${childTag}>
</${parentTag}>
`));
if (cfg.choiceType === 'single') {
// @ts-expect-error
el.serializedValue = 'other';
await el.registrationComplete;
expect(el.serializedValue).to.equal('other');
} else {
// @ts-expect-error
el.serializedValue = ['other'];
await el.registrationComplete;
expect(el.serializedValue).to.deep.equal(['other']);
}
});
it('can handle null and undefined modelValues', async () => {
const el = /** @type {ChoiceInputGroup} */ (await fixture(html`
<${parentTag} name="gender[]" .modelValue=${null}>
<${childTag} .choiceValue=${'male'}></${childTag}>
<${childTag} .choiceValue=${'female'}></${childTag}>
<${childTag} .choiceValue=${'other'}></${childTag}>
</${parentTag}>
`));
if (cfg.choiceType === 'single') {
expect(el.modelValue).to.equal('');
} else {
expect(el.modelValue).to.deep.equal([]);
}
el.modelValue = undefined;
await el.updateComplete;
if (cfg.choiceType === 'single') {
expect(el.modelValue).to.equal('');
} else {
expect(el.modelValue).to.deep.equal([]);
}
});
it('can handle complex data via choiceValue', async () => {
const date = new Date(2018, 11, 24, 10, 33, 30, 0);

View file

@ -123,7 +123,7 @@ export declare class FormControlHost {
* (think of an amount-input with a currency select box next to it), can set this
* to true to hide private internals in the formPath.
*/
_isRepropagationEndpoint: boolean;
protected _isRepropagationEndpoint: boolean;
connectedCallback(): void;
updated(changedProperties: import('@lion/core').PropertyValues): void;