From 5534369d4558ae70e1d1a4053c6c49d82b33039a Mon Sep 17 00:00:00 2001 From: gerjanvangeest Date: Mon, 5 Aug 2019 14:01:27 +0200 Subject: [PATCH] fix(form): sync submit and reset events instead of delegating --- packages/form/src/LionForm.js | 65 +++++++++++++++------------- packages/form/test/lion-form.test.js | 40 ++++++++++++++++- 2 files changed, 74 insertions(+), 31 deletions(-) diff --git a/packages/form/src/LionForm.js b/packages/form/src/LionForm.js index 442532091..9c3b084c6 100644 --- a/packages/form/src/LionForm.js +++ b/packages/form/src/LionForm.js @@ -1,4 +1,3 @@ -import { DelegateMixin } from '@lion/core'; import { LionFieldset } from '@lion/fieldset'; /** @@ -8,50 +7,58 @@ import { LionFieldset } from '@lion/fieldset'; * @extends LionFieldset */ // eslint-disable-next-line no-unused-vars -export class LionForm extends DelegateMixin(LionFieldset) { - get delegations() { - return { - ...super.delegations, - target: () => this.formElement, - events: [...super.delegations.events, 'submit', 'reset'], - methods: [...super.delegations.methods, 'submit', 'reset'], - }; - } - - constructor() { - super(); - this.__boundSubmit = this._submit.bind(this); - this.__boundReset = this._reset.bind(this); - } - +export class LionForm extends LionFieldset { connectedCallback() { - super.connectedCallback(); - this.addEventListener('submit', this.__boundSubmit); - this.addEventListener('reset', this.__boundReset); + if (super.connectedCallback) { + super.connectedCallback(); + } + this.__registerEventsForLionForm(); } disconnectedCallback() { - super.disconnectedCallback(); - this.removeEventListener('submit', this.__boundSubmit); - this.removeEventListener('reset', this.__boundReset); + if (super.disconnectedCallback) { + super.disconnectedCallback(); + } + this.__teardownEventsForLionForm(); } get formElement() { return this.querySelector('form'); } + submit() { + this.formElement.submit(); + } + + reset() { + this.formElement.reset(); + } + /** * As we use a native form there is no need for a role */ _setRole() {} // eslint-disable-line class-methods-use-this - _submit(ev) { - ev.preventDefault(); - this.submitGroup(); + __registerEventsForLionForm() { + this._submit = ev => { + ev.preventDefault(); + ev.stopPropagation(); + this.dispatchEvent(new Event('submit', { bubbles: true })); + this.submitGroup(); + }; + this.formElement.addEventListener('submit', this._submit); + + this._reset = ev => { + ev.preventDefault(); + ev.stopPropagation(); + this.dispatchEvent(new Event('reset', { bubbles: true })); + this.resetGroup(); + }; + this.formElement.addEventListener('reset', this._reset); } - _reset(ev) { - ev.preventDefault(); - this.resetGroup(); + __teardownEventsForLionForm() { + this.formElement.removeEventListener('submit', this._submit); + this.formElement.removeEventListener('rest', this._reset); } } diff --git a/packages/form/test/lion-form.test.js b/packages/form/test/lion-form.test.js index 4389976b0..f1edbdb99 100644 --- a/packages/form/test/lion-form.test.js +++ b/packages/form/test/lion-form.test.js @@ -1,4 +1,4 @@ -import { expect, fixture, html } from '@open-wc/testing'; +import { expect, fixture, html, oneEvent } from '@open-wc/testing'; import { spy } from 'sinon'; import '@lion/input/lion-input.js'; @@ -7,7 +7,7 @@ import '@lion/fieldset/lion-fieldset.js'; import '../lion-form.js'; describe('', () => { - it.skip('has a custom reset that gets triggered by native reset', async () => { + it('has a custom reset that gets triggered by native reset', async () => { const withDefaults = await fixture(html`
@@ -39,6 +39,24 @@ describe('', () => { }); }); + it('dispatches reset events', async () => { + const el = await fixture(html` + + + + + + `); + + setTimeout(() => el.reset()); + const resetEv = await oneEvent(el, 'reset'); + expect(resetEv).to.be.instanceOf(Event); + expect(resetEv.type).to.equal('reset'); + expect(resetEv.target).to.equal(el); + expect(resetEv.bubbles).to.be.true; + expect(resetEv.composed).to.be.false; + }); + it('works with the native submit event (triggered via a button)', async () => { const submitSpy = spy(); const el = await fixture(html` @@ -53,4 +71,22 @@ describe('', () => { button.click(); expect(submitSpy.callCount).to.equal(1); }); + + it('dispatches submit events', async () => { + const el = await fixture(html` + +
+ +
+
+ `); + const button = el.querySelector('button'); + setTimeout(() => button.click()); + const submitEv = await oneEvent(el, 'submit'); + expect(submitEv).to.be.instanceOf(Event); + expect(submitEv.type).to.equal('submit'); + expect(submitEv.target).to.equal(el); + expect(submitEv.bubbles).to.be.true; + expect(submitEv.composed).to.be.false; + }); });