fix(form-core): update child choice fields name attr to parent

This commit is contained in:
Joren Broekema 2020-10-12 12:26:30 +02:00
parent 838b362358
commit 247e64a3cc
4 changed files with 42 additions and 45 deletions

View file

@ -0,0 +1,5 @@
---
'@lion/form-core': patch
---
Ensure that the name of a child choice field is always synced with the parent choice field(set) when it changes. No longer error when a child is added with a different name than the parent, simply sync it.

View file

@ -156,6 +156,17 @@ const ChoiceGroupMixinImplementation = superclass =>
}); });
} }
/** @param {import('lit-element').PropertyValues} changedProperties */
updated(changedProperties) {
super.updated(changedProperties);
if (changedProperties.has('name') && this.name !== changedProperties.get('name')) {
this.formElements.forEach(child => {
// eslint-disable-next-line no-param-reassign
child.name = this.name;
});
}
}
disconnectedCallback() { disconnectedCallback() {
super.disconnectedCallback(); super.disconnectedCallback();
@ -171,7 +182,8 @@ const ChoiceGroupMixinImplementation = superclass =>
*/ */
addFormElement(child, indexToInsertAt) { addFormElement(child, indexToInsertAt) {
this._throwWhenInvalidChildModelValue(child); this._throwWhenInvalidChildModelValue(child);
this.__delegateNameAttribute(child); // eslint-disable-next-line no-param-reassign
child.name = this.name;
super.addFormElement(child, indexToInsertAt); super.addFormElement(child, indexToInsertAt);
} }
@ -283,24 +295,6 @@ const ChoiceGroupMixinImplementation = superclass =>
} }
} }
/**
* @param {FormControl} child
*/
__delegateNameAttribute(child) {
if (!child.name || child.name === this.name) {
// eslint-disable-next-line no-param-reassign
child.name = this.name;
} else {
throw new Error(
`The ${this.tagName.toLowerCase()} name="${
this.name
}" does not allow to register ${child.tagName.toLowerCase()} with custom names (name="${
child.name
}" given)`,
);
}
}
/** /**
* @override FormControlMixin * @override FormControlMixin
* @param {CustomEvent} ev * @param {CustomEvent} ev

View file

@ -74,7 +74,7 @@ export function runChoiceGroupMixinSuite({ parentTagString, childTagString } = {
); );
}); });
it('automatically sets the name property of child radios to its own name', async () => { it('automatically sets the name property of child fields to its own name', async () => {
const el = /** @type {ChoiceGroup} */ (await fixture(html` const el = /** @type {ChoiceGroup} */ (await fixture(html`
<${parentTag} name="gender"> <${parentTag} name="gender">
<${childTag} .choiceValue=${'female'} checked></${childTag}> <${childTag} .choiceValue=${'female'} checked></${childTag}>
@ -93,7 +93,26 @@ export function runChoiceGroupMixinSuite({ parentTagString, childTagString } = {
expect(el.formElements[2].name).to.equal('gender'); expect(el.formElements[2].name).to.equal('gender');
}); });
it('throws if a child element with a different name than the group tries to register', async () => { it('automatically updates the name property of child fields to its own name', async () => {
const el = /** @type {ChoiceGroup} */ (await fixture(html`
<${parentTag} name="gender">
<${childTag}></${childTag}>
<${childTag}></${childTag}>
</${parentTag}>
`));
expect(el.formElements[0].name).to.equal('gender');
expect(el.formElements[1].name).to.equal('gender');
el.name = 'gender2';
await el.updateComplete;
expect(el.formElements[0].name).to.equal('gender2');
expect(el.formElements[1].name).to.equal('gender2');
});
it('adjusts the name of a child element if it has a different name than the group', async () => {
const el = /** @type {ChoiceGroup} */ (await fixture(html` const el = /** @type {ChoiceGroup} */ (await fixture(html`
<${parentTag} name="gender"> <${parentTag} name="gender">
<${childTag} .choiceValue=${'female'} checked></${childTag}> <${childTag} .choiceValue=${'female'} checked></${childTag}>
@ -104,12 +123,9 @@ export function runChoiceGroupMixinSuite({ parentTagString, childTagString } = {
const invalidChild = /** @type {ChoiceGroup} */ (await fixture(html` const invalidChild = /** @type {ChoiceGroup} */ (await fixture(html`
<${childTag} name="foo" .choiceValue=${'male'}></${childTag}> <${childTag} name="foo" .choiceValue=${'male'}></${childTag}>
`)); `));
el.addFormElement(invalidChild);
expect(() => { await invalidChild.updateComplete;
el.addFormElement(invalidChild); expect(invalidChild.name).to.equal('gender');
}).to.throw(
'The choice-group name="gender" does not allow to register choice-group-input with custom names (name="foo" given)',
);
}); });
it('can set initial modelValue on creation', async () => { it('can set initial modelValue on creation', async () => {

View file

@ -96,24 +96,6 @@ export function runListboxMixinSuite(customConfig = {}) {
); );
}); });
it('throws if a child element with a different name than the group tries to register', async () => {
const el = await fixture(html`
<${tag} name="gender">
<${optionTag} .choiceValue=${'female'} checked></${optionTag}>
<${optionTag} .choiceValue=${'other'}></${optionTag}>
</${tag}>
`);
const invalidChild = await fixture(html`
<${optionTag} name="foo" .choiceValue=${'male'}></${optionTag}>
`);
expect(() => {
el.addFormElement(invalidChild);
}).to.throw(
`The ${cfg.tagString} name="gender" does not allow to register lion-option with custom names (name="foo" given)`,
);
});
it('can set initial modelValue on creation', async () => { it('can set initial modelValue on creation', async () => {
const el = await fixture(html` const el = await fixture(html`
<${tag} name="gender" .modelValue=${'other'}> <${tag} name="gender" .modelValue=${'other'}>