diff --git a/packages/field/src/FormRegistrarMixin.js b/packages/field/src/FormRegistrarMixin.js index a1e283d76..4de54eb15 100644 --- a/packages/field/src/FormRegistrarMixin.js +++ b/packages/field/src/FormRegistrarMixin.js @@ -63,12 +63,16 @@ export const FormRegistrarMixin = dedupeMixin( this.__hasBeenRendered = true; } - addFormElement(child) { + addFormElement(child, index) { // This is a way to let the child element (a lion-fieldset or lion-field) know, about its parent // eslint-disable-next-line no-param-reassign child.__parentFormGroup = this; - this.formElements.push(child); + if (index > 0) { + this.formElements.splice(index, 0, child); + } else { + this.formElements.push(child); + } } removeFormElement(child) { @@ -89,7 +93,14 @@ export const FormRegistrarMixin = dedupeMixin( return; } ev.stopPropagation(); - this.addFormElement(child); + + // Check for siblings to determine the right order to insert into formElements + // If there is no next sibling, index is -1 + let indexToInsertAt = -1; + if (this.formElements && Array.isArray(this.formElements)) { + indexToInsertAt = this.formElements.indexOf(child.nextElementSibling); + } + this.addFormElement(child, indexToInsertAt); } _onRequestToRemoveFormElement(ev) { diff --git a/packages/field/test-suites/FormRegistrationMixins.suite.js b/packages/field/test-suites/FormRegistrationMixins.suite.js index ab2b9ac12..08c60faa4 100644 --- a/packages/field/test-suites/FormRegistrationMixins.suite.js +++ b/packages/field/test-suites/FormRegistrationMixins.suite.js @@ -168,6 +168,44 @@ export const runRegistrationSuite = customConfig => { expect(el.formElements.length).to.equal(1); }); + it('adds elements to formElements in the right order', async () => { + const el = await fixture(html` + <${parentTag}> + <${childTag}> + <${childTag}> + <${childTag}> + + `); + + expect(el.formElements.length).to.equal(3); + + // In the middle + const secondChild = el.firstElementChild.nextElementSibling; + const newField = await fixture(html` + <${childTag}> + `); + secondChild.insertAdjacentElement('beforebegin', newField); + + expect(el.formElements.length).to.equal(4); + expect(el.formElements[1]).dom.to.equal(newField); + + // Prepending + const anotherField = await fixture(html` + <${childTag}> + `); + el.prepend(anotherField); + expect(el.formElements.length).to.equal(5); + expect(el.formElements[0]).dom.to.equal(anotherField); + + // Appending + const yetAnotherField = await fixture(html` + <${childTag}> + `); + el.appendChild(yetAnotherField); + expect(el.formElements.length).to.equal(6); + expect(el.formElements[5]).dom.to.equal(anotherField); + }); + // find a proper way to do this on polyfilled browsers it.skip('fires event "form-element-register" with the child as ev.target', async () => { const registerSpy = sinon.spy();