[w3c/webcomponents] Form associated custom elements: implicit submission (#815)

See discussion starting around https://github.com/w3c/webcomponents/issues/187#issuecomment-487171781.

[Implicit submission](https://html.spec.whatwg.org/#implicit-submission) allows things like pressing enter to automatically click a form's submit button.

In Chrome's current implementation of form-associated custom elements, pressing enter on a FACE will not trigger implicit submission. This is allowed by the spec, because the spec for implicit submission is quite vague. It kind of makes sense as a conservative default. We may want to tighten the spec to disallow any form of user-agent-provided implicit submission for FACE.

Web developers can get implicit submission behavior for their FACEs using code like

```js
const TYPES_THAT_BLOCK = new Set(['text', 'search', 'url', 'tel', 'email', 'password', 'date', 'month', 'week', 'time', 'datetime-local', 'number']);

this.addEventListener("keydown", e => {
 if (e.keyCode === 13) {
  const { form } = this.#internals;

  // Find the submit button
  // form.querySelector(':default') doesn't work due to 'form' content attribute.
  for (const control of form.elements) {
   if (control.matches(':default')) {
    if (!control.disabled) {
     control.click();
    }
    return;
   }
  }
  
  // If we reached here, there's no submit button.
  // See if there's a field that blocks implicit submission.
  if ([..form.elements].find(el => TYPES_THAT_BLOCK.has(el.type)) === undefined) {
   form.requestSubmit();
  }
 }
});
```

This is not great:

- It is a lot of boilerplate
- It is easy to get wrong and miss some subtleties
- It assumes implicit submission is done via the enter key, which is not guaranteed by the spec and may be different in different UAs.

The previous discussions were indicating that we should find a way to make it easy for web developers. There are two approaches.

One is an easymode that just lets you set a bit "make me implicitly submittable", e.g. `this.#internals.implicitlySubmittable = true`. Maybe we can also extend the list of elements that block implicit submission, with `this.#internals.blocksImplicitSubmission = true`.


The other is to improve the above code snippet by providing nicer building blocks. The result could be something like

```js
this.addEventListener("requestimplicitsubmit", () => {
 const { form } = this.#internals;
  const button = form.defaultButton;
  if (button) {
  if (!button.disabled) {
   button.click();
  }
 } else if (!form.implicitSubmissionBlocked) {
  form.requestSubmit();
 }
});
```

This version might still need `this.#internals.blocksImplicitSubmission = true` if we want to make that list extensible.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/w3c/webcomponents/issues/815

Received on Thursday, 16 May 2019 21:16:51 UTC