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


Most viewed posts


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 }) => {
            update().finally(async () => {
                sending = false;
                // Optionally if you'd like to reload the data for the current page after form submission.
                // This is the default behavior for use:enhance.
                await invalidateAll();
            });
        };
    }}
>
    <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 he below effect. You can also check out the live demo here!

Web Developer at Aftonbladet (Schibsted Media Group)
Any opinions on this blog are my own and do not reflect the views of my employer.
LinkedIn
Twitter
WordPress.org Profile
Visit my other blog

Comments 0
There are currently no comments.