Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: allow a mode of form.submit() that behaves like clicking a submit button #4187

Closed
domenic opened this issue Nov 21, 2018 · 17 comments · Fixed by #4597
Closed

Proposal: allow a mode of form.submit() that behaves like clicking a submit button #4187

domenic opened this issue Nov 21, 2018 · 17 comments · Fixed by #4597
Labels
addition/proposal New features or enhancements topic: forms

Comments

@domenic
Copy link
Member

domenic commented Nov 21, 2018

Right now, the following snippets of code behave differently:

form.submit();
const button = document.createElement('input');
button.type = 'submit';
form.append(button);
button.click();
button.remove();

Per https://html.spec.whatwg.org/#concept-form-submit, the second one gets a lot more useful behaviors: interactive validation, submit events, and the potential of replacement-enabled navigation when the document is not yet completely loaded.

Wouldn't it be nice if we could do

form.submit({ interactive: true });

or similar? (Bikeshed the name at your leisure.)

This is of special concern to folks trying to create custom form controls that behave like submit buttons, or for any attempts to explain the platform's elements in terms of imperative constructs.

Credit to @manucorporat for this idea; he pointed out that Ionic is currently using the hacky workaround for their custom submit button. That makes me sad and it would be nice if we could help them not do that.

/cc @tkent-google @rniwa @smaug---- @travisleithead for implementer thoughts.

@domenic domenic added addition/proposal New features or enhancements needs implementer interest Moving the issue forward requires implementers to express interest topic: forms labels Nov 21, 2018
@manucorporat
Copy link

manucorporat commented Nov 21, 2018

Thanks Domenic for introducing the proposal!

To add a little more context, the hack is required because, even so we have a <button> for accessibility reasons, it is inside the shadow dom of ion-button component, making it unable to submit the form.

@rniwa
Copy link

rniwa commented Nov 21, 2018

Seems like a good idea although maybe adding a new method would be cleaner since this is really a request to submit if the validation had passed. Another thing to consider is some aspects of it should be configurable. e.g. it's odd that the flag named interactive would trigger the firing of submit event.

@Yay295
Copy link
Contributor

Yay295 commented Nov 21, 2018

I think some of this is handled by HTMLFormElement.reportValidity().

@muan
Copy link
Member

muan commented Nov 21, 2018

It'd be nice if this can also support the case of having button[value] as a submitter.

GitHub has a similar hacky submit function as well, but it takes in an additional optional button argument to ensure we can retain the value when submitting the form. It's used for binding keyboard shortcuts on these buttons, for example:

image

@manucorporat
Copy link

@rniwa agreed! and adding a new method would also make it easier to detect when this new feature is available

@tkent-google
Copy link
Contributor

This sounds a good feature. I'll implement this in Chrome if this is standardized.
I agree with rniwa. We should have another function with a better name.

@annevk
Copy link
Member

annevk commented Nov 22, 2018

I agree with @muan that this should also have a submitter argument, if we're going to expose this primitive anyway. The slight complication that brings is some verification that it's indeed an okay submit button for the form.

@manucorporat
Copy link

manucorporat commented Nov 22, 2018

Extending what @muan said, it would be great to be able to simulate what a:
<button type="reset"> do, so maybe a "type" arguments that defaults to "submit" makes sense too:

(tentative names)

form.requestSubmit({
   type: "reset", // defaults to "submit"
   value: "somevalue", // defaults to undefined
   name: "somename", // defaults to undefined
})

equivalent to:

<button type="reset" name="somename" value="somevalue">

Submits without extra config:

form.requestSubmit()

equivalent to:

<button type="submit">

thoughts about what this hypothetical method should return?

@annevk
Copy link
Member

annevk commented Nov 22, 2018

Submitting is a primitive (taking a submitter), doesn't return anything, but you could imagine returning details about the resulting state: https://html.spec.whatwg.org/#concept-form-submit.

Resetting is a different primitive (does not take arguments), also doesn't return anything: https://html.spec.whatwg.org/#concept-form-reset.

I think that means we want two methods here. Return values could make sense, but would probably delay things somewhat as we'd have to make sure that the return value is what we want long term (returning undefined for now and upgrading later is also an option).

@manucorporat
Copy link

manucorporat commented Nov 22, 2018

@annevk you right!
actually, HTMLFormElement already has a reset() method that emits a cancellable ResetEvent, so we are fine.

(returning undefined for now and upgrading later is also an option)

absolutely, no need to make the proposal more complicated than it should be. There are already good ways to collect the submitted values

(tentative)

// equivalent to <input type="submit">
form.requestSubmit();

// equivalent to <input type="submit" name="somename" value="somevalue">
form.requestSubmit({
   value: "somevalue",
   name: "somename"
});

@annevk
Copy link
Member

annevk commented Nov 22, 2018

I'd make it take an actual element as that's the underlying primitive.

@travisleithead
Copy link
Member

This seems like a great feature. Glad it can fix hacky workarounds in at least GitHub and Ionic (and probably others). Edge team supports and would also be willing to ship.

@annevk annevk added needs concrete proposal Moving the issue forward requires someone to figure out a detailed plan and removed needs implementer interest Moving the issue forward requires implementers to express interest labels Nov 30, 2018
@tkent-google
Copy link
Contributor

tkent-google commented Apr 24, 2019

Now we have formdata event and we can add arbitrary entries with it. We don't need flexibility to specify value and name with the proposed API.

So, we should start with

void requestSubmit(HTMLElement? submitterButton);

It triggers submit with submitterButton as submitter and false as submitted from submit() method flag, which means triggers interactive form validation and fires submit event.

What do you think?

@annevk
Copy link
Member

annevk commented Apr 24, 2019

Yeah, that's the shape I want, except the IDL should be (optional arguments should use undefined, not null in JavaScript):

void requestSubmit(optional HTMLElement submitterButton);

What if you don't pass a submit button (i.e., <input type=image>, <input type=submit>, <button type=submit></button>), throw?

What about reset, we'd leave that alone for now?

@domenic
Copy link
Member Author

domenic commented Apr 24, 2019

What if you don't pass a submit button (i.e., , , ), throw?

Looking at https://html.spec.whatwg.org/#concept-form-submit it seems like the assumption is that submitter is a form-associated element. I think that's probably the right restriction for now.

Later, we can consider opening it up to form-associated custom elements as well, although for full parity it seems like we might need an additional way to say if the form-associated custom element "is a submit button", and thus its formmethod/formenctype/formaction attributes should be consulted.

What about reset, we'd leave that alone for now?

I'm not sure there's any value in exposing #concept-form-reset vs. just the existing reset() method. The reset method is just a wrapper around concept-form-reset plus a reentrancy guard. (Honestly, it may be a bug that that reentrancy guard is only in reset(), and not in #concept-form-reset.)

@tkent-google
Copy link
Contributor

What if you don't pass a submit button (i.e., , , ), throw?

Looking at https://html.spec.whatwg.org/#concept-form-submit it seems like the assumption is that submitter is a form-associated element. I think that's probably the right restriction for now.

IMO, we should start with a stricter rule, and loosen it if necessary. So, the function should throw a NotSupportedError (is it a right one?) if submitterButton is not a right control type or is not associated to the context form element.

Later, we can consider opening it up to form-associated custom elements as well, although for full parity it seems like we might need an additional way to say if the form-associated custom element "is a submit button", and thus its formmethod/formenctype/formaction attributes should be consulted.

I think we can create the submit button behavior with the current form-associated custom element proposal and requestSubmit().

class SubmitElement extends HTMLElement {
   ...
   handleClick() {
     this.#internals.setFormValue(this.getAttribute('value'));
     this.#internals.form.requestSubmit(this);  // UA consults formmethod/formenctype/formaction attributes of this element.
     this.#internals.setFormValue(null);
  }
}

@domenic
Copy link
Member Author

domenic commented Apr 25, 2019

IMO, we should start with a stricter rule, and loosen it if necessary. So, the function should throw a NotSupportedError (is it a right one?) if submitterButton is not a right control type or is not associated to the context form element.

That works for me. Good catch on checking its form owner; we should definitely do that.

I think we can create the submit button behavior with the current form-associated custom element proposal and requestSubmit().

So this would require first losening the requirement so that "the right control type" includes any form-associated custom element, right?

This also doesn't allow the implicit submission behavior of https://html.spec.whatwg.org/#implicit-submission . But maybe that is a good thing; I think most web developers hate that feature.

Otherwise I agree that this suffices. Very nice. Clever trick with the setting value before/after.

// UA consults formmethod/formenctype/formaction attributes of this element.

I missed formnovalidate, by the way.

domenic added a commit that referenced this issue May 6, 2019
@domenic domenic mentioned this issue May 6, 2019
3 tasks
@domenic domenic removed the needs concrete proposal Moving the issue forward requires someone to figure out a detailed plan label May 6, 2019
tkent-google added a commit to web-platform-tests/wpt that referenced this issue May 9, 2019
domenic added a commit that referenced this issue May 15, 2019
domenic added a commit that referenced this issue May 16, 2019
domenic pushed a commit to web-platform-tests/wpt that referenced this issue May 16, 2019
moz-v2v-gh pushed a commit to mozilla/gecko-dev that referenced this issue Jun 19, 2019
…), a=testonly

Automatic update from web-platform-tests
html: Add a test for form.requestSubmit()

Specification issue: whatwg/html#4187
Specification PR: whatwg/html#4597
--

wp5At-commits: 1de2d96f75cdc7a920b74a8f406262f16531ef0f
wpt-pr: 16743
xeonchen pushed a commit to xeonchen/gecko that referenced this issue Jun 19, 2019
…), a=testonly

Automatic update from web-platform-tests
html: Add a test for form.requestSubmit()

Specification issue: whatwg/html#4187
Specification PR: whatwg/html#4597
--

wp5At-commits: 1de2d96f75cdc7a920b74a8f406262f16531ef0f
wpt-pr: 16743
marcoscaceres pushed a commit to web-platform-tests/wpt that referenced this issue Jul 23, 2019
gecko-dev-updater pushed a commit to marco-c/gecko-dev-comments-removed that referenced this issue Oct 4, 2019
…), a=testonly

Automatic update from web-platform-tests
html: Add a test for form.requestSubmit()

Specification issue: whatwg/html#4187
Specification PR: whatwg/html#4597
--

wp5At-commits: 1de2d96f75cdc7a920b74a8f406262f16531ef0f
wpt-pr: 16743

UltraBlame original commit: d9fee4b7ddd070aaf762769226681d22b8473f86
gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified that referenced this issue Oct 4, 2019
…), a=testonly

Automatic update from web-platform-tests
html: Add a test for form.requestSubmit()

Specification issue: whatwg/html#4187
Specification PR: whatwg/html#4597
--

wp5At-commits: 1de2d96f75cdc7a920b74a8f406262f16531ef0f
wpt-pr: 16743

UltraBlame original commit: d9fee4b7ddd070aaf762769226681d22b8473f86
gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified-and-comments-removed that referenced this issue Oct 4, 2019
…), a=testonly

Automatic update from web-platform-tests
html: Add a test for form.requestSubmit()

Specification issue: whatwg/html#4187
Specification PR: whatwg/html#4597
--

wp5At-commits: 1de2d96f75cdc7a920b74a8f406262f16531ef0f
wpt-pr: 16743

UltraBlame original commit: d9fee4b7ddd070aaf762769226681d22b8473f86
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
addition/proposal New features or enhancements topic: forms
Development

Successfully merging a pull request may close this issue.

8 participants