I'm working with Svelte 5 and using Superforms for form handling. My goal is to bind a CalendarDate object from a custom DatePicker component to a Superforms field and then convert that CalendarDate to a string before submitting the form. However, when I submit the form, the value is not getting correctly passed and saved. It always goes to the 'NOTHING' default value, but al the logs show a if the reactivity and the changes works as expected.
Here's the important bit of the component:
<script lang="ts"> import type { DateValue } from '@internationalized/date'; import { DatePicker } from 'bits-ui'; interface Props { label?: string, selectedValue?: DateValue, width?: string, padding?: string, borderRadius? : string } let { label, selectedValue = $bindable(), width = '100%', borderRadius = '7px', padding = '0.75rem' }: Props = $props()</script><div class="input-wrapper flex flex-col" style="width: {width};"><DatePicker.Root weekdayFormat="short" fixedWeeks={true} bind:value={selectedValue}><DatePicker.Label class="pb-2 pl-1 text-sm-typo">{label}</DatePicker.Label><DatePicker.Input style="border-radius: {borderRadius}; width: {width} padding: {padding}"> {#snippet children({ segments })} {#each segments as { part, value }} {#if part === 'literal'}<DatePicker.Segment {part} > {value}</DatePicker.Segment> {:else}<DatePicker.Segment {part} > {value}</DatePicker.Segment> {/if} {/each}<DatePicker.Trigger>
Then the +page.svelte:
<script lang="ts"> import DatePicker from "$src/components/elements/dates/DatePicker.svelte"; import { superForm } from "sveltekit-superforms/client"; import ShinyCta from "$src/components/elements/buttons/ShinyCTA.svelte"; import { CalendarDate, parseDate } from "@internationalized/date"; let { data } = $props(); const { form, errors, enhance, message } = superForm(data.form, { validators: 'clear', }); let defaultValue = new CalendarDate(1997, 1, 9) let calendarDate: CalendarDate | undefined = $state($form.testDate ? parseDate($form.testDate) : defaultValue) $effect(()=> { if (calendarDate) { $form.testDate = calendarDate.toString(); // Convert CalendarDate to string }})</script><form action="" method="post" use:enhance><DatePicker bind:selectedValue={calendarDate}/><input type="hidden" name="testDate" value={$form.testDate || 'NOTHING'} /><ShinyCta type='submit' btnWidth='100%'>Submit</ShinyCta></form>
And the +page.server.ts:
import { superValidate } from "sveltekit-superforms/server";import type { PageServerLoad } from "./$types";import { zod } from "sveltekit-superforms/adapters";import { testSchema } from "./testValidation";import type { Actions } from "@sveltejs/kit";export const load: PageServerLoad = async () => { const form = await superValidate(zod(testSchema)) return { form }};export const actions: Actions = { default: async ({ request }) => { const form = await superValidate(request, zod(testSchema)); if (!form.valid) { console.log("Form invalid:", form.errors); return { form }; } // Extract the string date for database storage console.log('FORM DATA', form.data) // Save to the database (e.g., PostgreSQL) // await db.insert({ date: testDate }); return { form, success: true }; }};
The form validation should be as a String? Or can I make it expect a CalendarDate object (eventhough I'd like to store the date in my db as a ISO string)