Created
May 13, 2023 13:46
-
-
Save nasheomirro/5f542b984c30cd8db437654a4b8d75f7 to your computer and use it in GitHub Desktop.
utility for handling forms on the client side, I tried making it similar to traditional handling of form actions.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import type { FormEventHandler } from 'svelte/elements'; | |
import { writable } from 'svelte/store'; | |
type Message = { | |
type: 'error' | 'success'; | |
text: string; | |
}; | |
type FormStoreValues = { | |
loading: boolean; | |
message?: Message; | |
}; | |
// taken from the `FormEventHandler` type | |
type CustomFormHandler = (CustomFormEvent: { | |
event: Event & { currentTarget: EventTarget & HTMLFormElement }; | |
formData: FormData; | |
success: (message: string) => Message; | |
error: (message: string) => Message; | |
}) => Promise<Message | undefined> | Message | undefined; | |
/** | |
* makes it easier to write submit handlers that are similar to how | |
* form actions are done server-side. Note that `event.preventDefault` is already called. | |
*/ | |
export const createForm = (handler: CustomFormHandler) => { | |
const store = writable<FormStoreValues>({ | |
loading: false | |
}); | |
const handleSubmit: FormEventHandler<HTMLFormElement> = async (event) => { | |
event.preventDefault(); | |
store.update((state) => ({ ...state, loading: true })); | |
const formData = new FormData(event.currentTarget); | |
const message = await handler({ | |
event, | |
formData, | |
error: (message) => ({ text: message, type: 'error' }), | |
success: (message) => ({ text: message, type: 'success' }) | |
}); | |
store.update((state) => ({ ...state, loading: false, message: message || state.message })); | |
}; | |
return [store, handleSubmit] as const; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script lang="ts"> | |
import { createForm } from '$lib/utils/createForm'; | |
const [form, handleSubmit] = createForm(async ({ formData, error, success }) => { | |
const email = formData.get('email') as string | undefined; | |
const password = formData.get('password') as string | undefined; | |
if (!email || !password) return error('Missing Credentials'); | |
// ... do your stuff | |
return success('Login complete!'); | |
}); | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment