Skip to content

Instantly share code, notes, and snippets.

@nasheomirro
Created May 13, 2023 13:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nasheomirro/5f542b984c30cd8db437654a4b8d75f7 to your computer and use it in GitHub Desktop.
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.
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;
};
<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