Implementing Form Confirmation Dialog #679
-
Hello Everyone,
Below is a snippet of my current code:
import { z } from "zod";
export const setupSchema = z
.object({
username: z.string().min(3).max(20),
password: z.string().min(3).max(100),
confirmPassword: z.string().min(3).max(100),
})
.superRefine(({ password, confirmPassword }, ctx) => {
if (password !== confirmPassword) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: "Passwords do not match",
path: ["confirmPassword"],
});
}
});
export type SetupSchema = typeof setupSchema;
import type { Actions, PageServerLoad } from "./$types";
import { fail } from "@sveltejs/kit";
import { superValidate } from "sveltekit-superforms/client";
import { setupSchema } from "./setup-schema";
export const load: PageServerLoad = async () => {
return {
form: await superValidate(setupSchema),
};
};
export const actions: Actions = {
default: async (event) => {
const form = await superValidate(event, setupSchema);
if (!form.valid) return fail(400, { form });
return { form };
},
};
<script lang="ts">
import type { SuperValidated } from "sveltekit-superforms";
import type { FormOptions } from "formsnap";
import type { SetupSchema } from "./schema";
import { goto } from "$app/navigation";
import { toast } from "svelte-sonner";
import { setupSchema } from "./schema";
import * as Form from "$lib/components/ui/form";
import * as AlertDialog from "$lib/components/ui/alert-dialog";
export let form: SuperValidated<SetupSchema>;
let formEl: HTMLFormElement;
let disableSubmit = false;
let showDialog = false;
let confirmed = false;
const options: FormOptions<SetupSchema> = {
multipleSubmits: "prevent",
onSubmit({ formData, cancel }) {
const data = Object.fromEntries(formData);
const result = setupSchema.safeParse(data);
if (result.success && !confirmed) {
cancel();
showDialog = true;
} else {
confirmed = false;
}
},
onResult({ result }) {
if (result.type !== "success") {
return;
}
toast.success("Setup complete!", {
description: "You can now login with your admin account.",
});
disableSubmit = false;
setTimeout(() => {
goto("/", { invalidateAll: true });
}, 2000);
},
};
</script>
<Form.Root
schema={setupSchema}
{form}
{options}
let:config
let:enhance
asChild
>
<form method="POST" class="space-y-2" use:enhance bind:this={formEl}>
<Form.Field {config} name="username">
<Form.Item>
<Form.Label>Username</Form.Label>
<Form.Input placeholder="admin username" />
<Form.Validation />
</Form.Item>
</Form.Field>
<Form.Field {config} name="password">
<Form.Item>
<Form.Label>Password</Form.Label>
<Form.Input type="password" placeholder="••••••••••" />
<Form.Validation />
</Form.Item>
</Form.Field>
<Form.Field {config} name="confirmPassword">
<Form.Item>
<Form.Label>Confirm Password</Form.Label>
<Form.Input type="password" placeholder="••••••••••" />
<Form.Validation />
</Form.Item>
</Form.Field>
<Form.Button class="w-full" disabled={disableSubmit}>
Submit
</Form.Button>
</form>
</Form.Root>
<AlertDialog.Root bind:open={showDialog}>
<AlertDialog.Content>
<AlertDialog.Header>
<AlertDialog.Title>Are you absolutely sure?</AlertDialog.Title>
<AlertDialog.Description>
This action cannot be undone. This will permanently create the
admin account and securely store the associated data on the
server.
</AlertDialog.Description>
</AlertDialog.Header>
<AlertDialog.Footer>
<AlertDialog.Cancel
on:click={() => {
confirmed = false;
formEl.reset();
}}>Cancel</AlertDialog.Cancel
>
<AlertDialog.Action
disabled={disableSubmit}
on:click={() => {
confirmed = true;
disableSubmit = true;
formEl.requestSubmit();
}}
>
Submit
</AlertDialog.Action>
</AlertDialog.Footer>
</AlertDialog.Content>
</AlertDialog.Root> |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 1 reply
-
Have u not encountered an issue with updating the fields value reactively? Let's say that u got an edit button etc and onclick of it, u need to populate the form with data. How would u do it? When u click on another item's edit button, the form data gets stuck with the previous item's data. That's my scenario. I wonder if there is something to do with let:config because form.data gets changed but no change in the fields value. |
Beta Was this translation helpful? Give feedback.
-
Thank you for your response. Later that day, I achieved what I wanted through experimentation and searching in the documentation to find a method suitable for me. Here's what I came up with: <script lang="ts">
import type { SuperValidated } from "sveltekit-superforms";
import type { FormOptions } from "formsnap";
import type { SetupSchema } from "./schema";
import { setupSchema } from "./schema";
import * as Form from "$shadcn/form";
import * as AlertDialog from "$shadcn/alert-dialog";
export let form: SuperValidated<SetupSchema>;
let formEl: HTMLFormElement;
let disableSubmit = false;
let showDialog = false;
let confirmed = false;
const options: FormOptions<SetupSchema> = {
multipleSubmits: "prevent",
onSubmit({ formData, cancel }) {
const data = Object.fromEntries(formData);
const result = setupSchema.safeParse(data);
if (result.success && !confirmed) {
cancel();
showDialog = true;
} else {
confirmed = false;
}
},
onResult() {
disableSubmit = false;
}
};
</script>
<Form.Root schema={setupSchema} {form} {options} let:config let:enhance asChild>
<form method="POST" class="space-y-4" use:enhance bind:this={formEl}>
<Form.Field {config} name="username">
<Form.Item>
<Form.Label>Username</Form.Label>
<Form.Input placeholder="admin username" />
<Form.Validation />
</Form.Item>
</Form.Field>
<Form.Field {config} name="password">
<Form.Item>
<Form.Label>Password</Form.Label>
<Form.Input type="password" placeholder="••••••••••" />
<Form.Validation />
</Form.Item>
</Form.Field>
<Form.Field {config} name="confirmPassword">
<Form.Item>
<Form.Label>Confirm Password</Form.Label>
<Form.Input type="password" placeholder="••••••••••" />
<Form.Validation />
</Form.Item>
</Form.Field>
<Form.Button class="w-full" disabled={disableSubmit}>
Submit
</Form.Button>
</form>
</Form.Root>
<AlertDialog.Root bind:open={showDialog}>
<AlertDialog.Content>
<AlertDialog.Header>
<AlertDialog.Title>Are you absolutely sure?</AlertDialog.Title>
<AlertDialog.Description>
This action cannot be undone. This will permanently create the
admin account and securely store the associated data on the
server.
</AlertDialog.Description>
</AlertDialog.Header>
<AlertDialog.Footer>
<AlertDialog.Cancel
on:click={() => {
confirmed = false;
formEl.reset();
}}>
Cancel
</AlertDialog.Cancel>
<AlertDialog.Action
disabled={disableSubmit}
on:click={() => {
confirmed = true;
disableSubmit = true;
formEl.requestSubmit();
}}
>
Submit
</AlertDialog.Action>
</AlertDialog.Footer>
</AlertDialog.Content>
</AlertDialog.Root> |
Beta Was this translation helpful? Give feedback.
Thank you for your response. Later that day, I achieved what I wanted through experimentation and searching in the documentation to find a method suitable for me. Here's what I came up with: