Skip to content

Commit 2f15fd3

Browse files
committed
add form requestsubmit
1 parent 9687aa1 commit 2f15fd3

File tree

4 files changed

+121
-0
lines changed

4 files changed

+121
-0
lines changed

docs/index.html

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,20 @@ <h1>GitHub Feature Support Table</h1>
565565
<td data-supported="true"><div>76+</div></td>
566566
<td data-supported="true"><div>15.0+</div></td>
567567
</tr>
568+
<tr>
569+
<th>
570+
<a href="https://developer.mozilla.org/docs/Web/API/HTMLFormElement/requestSubmit">
571+
<code>HTMLFormElement.requestSubmit</code>
572+
</a>
573+
</th>
574+
<td data-polyfill="formRequestSubmit"><div>*</div></td>
575+
<td data-supported="true"><div>76+</div></td>
576+
<td data-supported="true"><div>79+</div></td>
577+
<td data-supported="true"><div>75+</div></td>
578+
<td data-supported="false"<div>*</div></td>
579+
<td data-supported="true"><div>63+</div></td>
580+
<td data-supported="true"><div>12.0+</div></td>
581+
</tr>
568582
<tr>
569583
<th>
570584
<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwn">

src/form-requestsubmit.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
export function requestSubmit(
2+
this: HTMLFormElement,
3+
submitter: HTMLButtonElement | HTMLInputElement | null = null
4+
): void {
5+
const event = new SubmitEvent('submit', {bubbles: true, cancelable: true, submitter})
6+
let input
7+
if (submitter && submitter.name) {
8+
input = Object.assign(document.createElement('input'), {
9+
type: 'hidden',
10+
hidden: true,
11+
name: submitter.name,
12+
value: submitter.value
13+
})
14+
this.append(input)
15+
}
16+
this.checkValidity() && !this.dispatchEvent(event) && this.submit()
17+
input?.remove()
18+
}
19+
20+
export function isSupported(): boolean {
21+
return 'requestSubmit' in HTMLFormElement.prototype && typeof HTMLFormElement.prototype.requestSubmit === 'function'
22+
}
23+
24+
export function isPolyfilled(): boolean {
25+
return HTMLFormElement.prototype.requestSubmit === requestSubmit
26+
}
27+
28+
export function apply(): void {
29+
if (!isSupported()) {
30+
HTMLFormElement.prototype.requestSubmit = requestSubmit
31+
}
32+
}

src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import * as arrayAt from './arraylike-at.js'
55
import * as cryptoRandomUUID from './crypto-randomuuid.js'
66
import * as elementReplaceChildren from './element-replacechildren.js'
77
import * as eventAbortSignal from './event-abortsignal.js'
8+
import * as formRequestSubmit from './form-requestsubmit.js'
89
import * as objectHasOwn from './object-hasown.js'
910
import * as promiseAllSettled from './promise-allsettled.js'
1011
import * as promiseAny from './promise-any.js'
@@ -60,6 +61,7 @@ export const polyfills = {
6061
cryptoRandomUUID,
6162
elementReplaceChildren,
6263
eventAbortSignal,
64+
formRequestSubmit,
6365
objectHasOwn,
6466
promiseAllSettled,
6567
promiseAny,

test/form-requestsubmit.js

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import {requestSubmit, apply, isPolyfilled, isSupported} from '../lib/form-requestsubmit.js'
2+
3+
describe('requestSubmit', () => {
4+
let form
5+
beforeEach(() => {
6+
form = document.createElement('form')
7+
document.body.append(form)
8+
})
9+
afterEach(() => {
10+
form.remove()
11+
})
12+
13+
it('has standard isSupported, isPolyfilled, apply API', () => {
14+
expect(isSupported).to.be.a('function')
15+
expect(isPolyfilled).to.be.a('function')
16+
expect(apply).to.be.a('function')
17+
expect(isSupported()).to.be.a('boolean')
18+
expect(isPolyfilled()).to.equal(false)
19+
})
20+
21+
it('does not dispatch or submit for invalid forms', () => {
22+
const input = document.createElement('input')
23+
input.required = true
24+
form.append(input)
25+
let called = false
26+
form.addEventListener('submit', () => {
27+
called = true
28+
})
29+
requestSubmit.call(form)
30+
expect(called).to.equal(false)
31+
})
32+
33+
it('dispatches submit event', () => {
34+
const input = document.createElement('input')
35+
form.append(input)
36+
let called = false
37+
form.addEventListener('submit', event => {
38+
called = true
39+
event.stopPropagation()
40+
})
41+
requestSubmit.call(form)
42+
expect(called).to.equal(true)
43+
})
44+
45+
it('passes submitter in event', () => {
46+
const input = document.createElement('input')
47+
input.type = 'button'
48+
form.append(input)
49+
let submitter = null
50+
form.addEventListener('submit', event => {
51+
submitter = event.submitter
52+
event.stopPropagation()
53+
})
54+
requestSubmit.call(form, input)
55+
expect(submitter).to.equal(input)
56+
})
57+
58+
it('includes the input value in FormData', () => {
59+
const input = document.createElement('input')
60+
input.type = 'button'
61+
input.name = 'foo'
62+
input.value = '1'
63+
form.append(input)
64+
let formdata = null
65+
form.addEventListener('submit', event => {
66+
formdata = new FormData(form)
67+
event.stopPropagation()
68+
})
69+
requestSubmit.call(form, input)
70+
expect(formdata.get('foo')).to.equal('1')
71+
expect(Array.from(form.querySelectorAll('input')).length).to.equal(1)
72+
})
73+
})

0 commit comments

Comments
 (0)