admin管理员组文章数量:1122846
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)
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)
Share Improve this question asked Nov 22, 2024 at 10:43 ErosiqueErosique 11 bronze badge 3 |1 Answer
Reset to default 0After tying I just simplified my approach and created a Hidden input to store the DateValue | CalendarDate value type of the Date Picker BitsUi component after parsing it into a string with toString and sync it with the Component Value with the 'onValueChange' prop. Like this:
DatePicker.svelte:
<script lang="ts">
import { parseDate, type CalendarDate, type DateValue } from '@internationalized/date';
import { DatePicker } from 'bits-ui';
interface Props {
label?: string,
width?: string,
padding?: string,
borderRadius?: string,
testDate: string
}
let { testDate = $bindable(), label, width = '100%', borderRadius = '7px', padding = '0.75rem' }: Props = $props()
let calendarDate: DateValue = $state(parseDate(testDate))
</script>
<div class="input-wrapper flex flex-col" style="width: {width};">
<input type="hidden" name="testDate" bind:value={testDate}>
<DatePicker.Root weekdayFormat="short" fixedWeeks={true} bind:value={calendarDate} onValueChange={(value) => testDate = value.toString()}>
And then in 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 { today } from "@internationalized/date";
let { data } = $props();
const { form, enhance } = superForm(data.form);
if(!$form.testDate) {
$form.testDate = today('UTC').toString()
}
</script>
<form action="" method="post" use:enhance>
<DatePicker bind:testDate={$form.testDate}/>
<ShinyCta type='submit' btnWidth='100%'>Submit</ShinyCta>
</form>
IMPORTANT!: Just make sure to put the same name attribute than the one expected by the form!! That was giving me errors when not matching!
本文标签: sveltekitSvelte 5 and Superforms Error Submiting Value of a DatePicker ComponentStack Overflow
版权声明:本文标题:sveltekit - Svelte 5 and Superforms: Error Submiting Value of a DatePicker Component - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736304404a1932222.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
<input type=date>
for the date selection and the value is sent just fine. (The input already uses astring
, so I converted it to a full ISO 8601 date/time to differentiate.) – brunnerh Commented Nov 22, 2024 at 16:40'NOTHING'
value on the page after the submit: That would be expected because you don't load anything in yourload
function. – brunnerh Commented Nov 22, 2024 at 17:00