ข้ามไปยังเนื้อหา

Forms & Inputs

form รวม binding, runes และ event เข้าด้วยกัน แต่ละ field bind กับ state; validation derive จาก state นั้น; submit อ่านค่าจาก state เดียวกัน นี่คือรูปแบบของ form จริง:

<script>
let email = $state('');
let password = $state('');
// validation DERIVE จาก field — ไม่เก็บแยกต่างหาก
let emailValid = $derived(/^[^@]+@[^@]+\.[^@]+$/.test(email));
let passwordValid = $derived(password.length >= 8);
let formValid = $derived(emailValid && passwordValid);
</script>
<input type="email" bind:value={email} placeholder="Email" />
{#if email && !emailValid}<small>ใส่ email ที่ถูกต้อง</small>{/if}
<input type="password" bind:value={password} placeholder="Password" />
{#if password && !passwordValid}<small>อย่างน้อย 8 ตัวอักษร</small>{/if}

ไอเดียสำคัญ: validation ถูก derive ไม่ใช่เก็บ emailValid คำนวณใหม่อัตโนมัติทุกครั้งที่ email เปลี่ยน — ไม่มีขั้นตอน “revalidate” ให้ลืม นี่คือหลัก “derive อย่า sync” จากบท effect มาใช้กับ form

ผูก onsubmit เข้ากับ <form> และเรียก e.preventDefault() เพื่อหยุด navigation ปกติของ browser แล้วทำงานกับ state ที่รวบรวมมา:

<script>
let submitting = $state(false);
async function handleSubmit(e) {
e.preventDefault(); // Svelte 5 ไม่มี on:submit|preventDefault modifier
if (!formValid) return;
submitting = true;
await createAccount({ email, password });
submitting = false;
}
</script>
<form onsubmit={handleSubmit}>
<!-- fields… -->
<button type="submit" disabled={!formValid || submitting}>
{submitting ? 'Creating…' : 'Sign up'}
</button>
</form>

สังเกตว่า button ที่ disabled derive จาก formValid และ submitting — UI ถูกต้องเสมอโดยไม่ต้อง toggle เอง

flowchart LR
  input["inputs (bind:value)"] --> state["field state"]
  state --> valid["$derived validation"]
  valid --> button["submit button enable/disable"]
  button --> submit["onsubmit → preventDefault → ทำงาน"]
form: bind, derive, submit

บทนี้จัดการ form ทั้งหมดบน client — โอเคสำหรับ local state และเคสง่าย ๆ แต่แอปจริงต้องการข้อมูลบน server: การ persist, auth, validation ที่เชื่อถือได้ นั่นคือสิ่งที่ SvelteKit form actions (โมดูลถัดไป) ให้มา — form แบบ progressive-enhancement ที่ทำงานทั้งมีและไม่มี JavaScript validate บน server client-side bind: + $derived ให้ UX ที่ตอบสนอง; SvelteKit ให้ pipeline แบบ full-stack

ควรจัดการ state ของ form validation ยังไง?
หยุด browser navigate ตอน submit form ใน Svelte 5 ยังไง?
ทำไมถึง derive ค่า `disabled` ของ submit button?
client-side form handling ไม่ได้ให้อะไร?