-
Notifications
You must be signed in to change notification settings - Fork 44
/
default-submit-handler.ts
55 lines (49 loc) · 1.65 KB
/
default-submit-handler.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import type { SuccessResponse, FetchResponse } from './error';
import { FelteSubmitError } from './error';
export function createDefaultSubmitHandler(form?: HTMLFormElement) {
if (!form) return;
return async function onSubmit(): Promise<SuccessResponse> {
let body: FormData | URLSearchParams = new FormData(form);
const action = new URL(form.action);
const method =
form.method.toLowerCase() === 'get'
? 'get'
: action.searchParams.get('_method') || form.method;
let enctype = form.enctype;
if (form.querySelector('input[type="file"]')) {
enctype = 'multipart/form-data';
}
if (method === 'get' || enctype === 'application/x-www-form-urlencoded') {
body = new URLSearchParams(body as any);
}
let fetchOptions: RequestInit;
if (method === 'get') {
(body as URLSearchParams).forEach((value, key) => {
action.searchParams.append(key, value);
});
fetchOptions = { method, headers: { Accept: 'application/json' } };
} else {
fetchOptions = {
method,
body,
headers: {
// If `Content-Type` is set on multipart/form-data, boundary will be missing
// See: https://github.com/pablo-abc/felte/issues/165
...(enctype !== 'multipart/form-data' && {
'Content-Type': enctype,
}),
Accept: 'application/json',
},
};
}
const response: FetchResponse = await window.fetch(
action.toString(),
fetchOptions
);
if (response.ok) return response;
throw new FelteSubmitError(
'An error occurred while submitting the form',
response
);
};
}