fix(form): sync submit and reset events instead of delegating
This commit is contained in:
parent
7ac9d88921
commit
5534369d45
2 changed files with 74 additions and 31 deletions
|
|
@ -1,4 +1,3 @@
|
||||||
import { DelegateMixin } from '@lion/core';
|
|
||||||
import { LionFieldset } from '@lion/fieldset';
|
import { LionFieldset } from '@lion/fieldset';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -8,50 +7,58 @@ import { LionFieldset } from '@lion/fieldset';
|
||||||
* @extends LionFieldset
|
* @extends LionFieldset
|
||||||
*/
|
*/
|
||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line no-unused-vars
|
||||||
export class LionForm extends DelegateMixin(LionFieldset) {
|
export class LionForm extends 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
connectedCallback() {
|
connectedCallback() {
|
||||||
super.connectedCallback();
|
if (super.connectedCallback) {
|
||||||
this.addEventListener('submit', this.__boundSubmit);
|
super.connectedCallback();
|
||||||
this.addEventListener('reset', this.__boundReset);
|
}
|
||||||
|
this.__registerEventsForLionForm();
|
||||||
}
|
}
|
||||||
|
|
||||||
disconnectedCallback() {
|
disconnectedCallback() {
|
||||||
super.disconnectedCallback();
|
if (super.disconnectedCallback) {
|
||||||
this.removeEventListener('submit', this.__boundSubmit);
|
super.disconnectedCallback();
|
||||||
this.removeEventListener('reset', this.__boundReset);
|
}
|
||||||
|
this.__teardownEventsForLionForm();
|
||||||
}
|
}
|
||||||
|
|
||||||
get formElement() {
|
get formElement() {
|
||||||
return this.querySelector('form');
|
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
|
* As we use a native form there is no need for a role
|
||||||
*/
|
*/
|
||||||
_setRole() {} // eslint-disable-line class-methods-use-this
|
_setRole() {} // eslint-disable-line class-methods-use-this
|
||||||
|
|
||||||
_submit(ev) {
|
__registerEventsForLionForm() {
|
||||||
ev.preventDefault();
|
this._submit = ev => {
|
||||||
this.submitGroup();
|
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) {
|
__teardownEventsForLionForm() {
|
||||||
ev.preventDefault();
|
this.formElement.removeEventListener('submit', this._submit);
|
||||||
this.resetGroup();
|
this.formElement.removeEventListener('rest', this._reset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 { spy } from 'sinon';
|
||||||
|
|
||||||
import '@lion/input/lion-input.js';
|
import '@lion/input/lion-input.js';
|
||||||
|
|
@ -7,7 +7,7 @@ import '@lion/fieldset/lion-fieldset.js';
|
||||||
import '../lion-form.js';
|
import '../lion-form.js';
|
||||||
|
|
||||||
describe('<lion-form>', () => {
|
describe('<lion-form>', () => {
|
||||||
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`
|
const withDefaults = await fixture(html`
|
||||||
<lion-form
|
<lion-form
|
||||||
><form>
|
><form>
|
||||||
|
|
@ -39,6 +39,24 @@ describe('<lion-form>', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('dispatches reset events', async () => {
|
||||||
|
const el = await fixture(html`
|
||||||
|
<lion-form>
|
||||||
|
<form>
|
||||||
|
<lion-input name="firstName" .modelValue="${'Foo'}"></lion-input>
|
||||||
|
</form>
|
||||||
|
</lion-form>
|
||||||
|
`);
|
||||||
|
|
||||||
|
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 () => {
|
it('works with the native submit event (triggered via a button)', async () => {
|
||||||
const submitSpy = spy();
|
const submitSpy = spy();
|
||||||
const el = await fixture(html`
|
const el = await fixture(html`
|
||||||
|
|
@ -53,4 +71,22 @@ describe('<lion-form>', () => {
|
||||||
button.click();
|
button.click();
|
||||||
expect(submitSpy.callCount).to.equal(1);
|
expect(submitSpy.callCount).to.equal(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('dispatches submit events', async () => {
|
||||||
|
const el = await fixture(html`
|
||||||
|
<lion-form>
|
||||||
|
<form>
|
||||||
|
<button type="submit">submit</button>
|
||||||
|
</form>
|
||||||
|
</lion-form>
|
||||||
|
`);
|
||||||
|
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;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue