Useful Snippets

Welcome!


This blog is used to collect useful snippets related to Linux, PHP, MySQL and more. Feel free to post comments with improvements or questions!

Are your smart devices spying on you? Make better purchasing choices and find products that respect your privacy at Unwanted.cloud

RSS Latest posts from my personal blog


Subscribe to RSS feed


Add a loading indicator to a Form Action in SvelteKit

Stanislav KhromovStanislav Khromov

In order to implement a loading indicator in a SvelteKit form using use:enhance Form Actions, you need to customize use:enhance.

The basic idea is:

  1. Create a sending boolean variable that represents whether the form is submitting or not
  2. Customize use enhance and set sending to true when the form starts loading, and then to false when the form finishes.

Let’s look at an example of a component where you send in your name and it returns back “Hello ${name}!”.

<script>
    import { enhance } from "$app/forms";
    import { invalidateAll } from "$app/navigation";
    export let form;
    let sending = false;
</script>

<h1>Greeter</h1>

{#if sending}
    <p>
        Sending...
    </p>
{:else if form}
    <p>{form?.greeting}</p>
{:else}
    <p>What's your name?</p>
{/if}

<form
    method="POST"
    use:enhance={() => {
        sending = true;
        return ({ update }) => {
            // Set invalidateAll to false if you don't want to reload page data when submitting
            update({ invalidateAll: true }).finally(async () => { 
                sending = false;
            });
        };
    }}
>
    <input disabled={sending} type="text" name="name" autofocus />
    <button disabled={sending} type="submit">Submit</button>
</form>

And here is the Form Action:

import type { Actions } from './$types';

export const actions = {
    default: async ({ request }) => {
        const data = await request.formData();
        const text = data.get('name');
        await new Promise((resolve) => setTimeout(resolve, 3000));
        return {
            greeting: `Hello ${text}!`,
        }
    },
} satisfies Actions;

Some CSS was ommitted. With this component, we get the below effect. You can also check out the live demo here!

Full-stack impostor syndrome sufferer & Software Engineer at Schibsted Media Group

Comments 2