|
9 | 9 | import { page } from '$app/stores' |
10 | 10 | import { toast } from 'svelte-sonner' |
11 | 11 | import SlugDisplay from './slug-display.svelte' |
| 12 | + import { debounce } from 'throttle-debounce' |
12 | 13 |
|
13 | 14 | export let data: SuperValidated<Infer<typeof createProjectSchema>> |
14 | 15 |
|
15 | 16 | let open = false |
16 | 17 |
|
17 | 18 | const form = superForm(data, { |
18 | 19 | validators: zodClient(createProjectSchema), |
| 20 | + validationMethod: 'oninput', |
19 | 21 | async onUpdated({ form }) { |
20 | 22 | if (form.message) { |
21 | 23 | if ($page.status >= 400) { |
|
25 | 27 | open = false |
26 | 28 | } |
27 | 29 | } |
| 30 | + }, |
| 31 | + async onChange(event) { |
| 32 | + // if name changed the server error is no longer relevant |
| 33 | + if (event.paths.includes('name')) { |
| 34 | + nameServerError = [] |
| 35 | + } |
| 36 | +
|
| 37 | + $errors.name = [...nameServerError, ...($errors.name || [])] |
28 | 38 | } |
29 | 39 | }) |
30 | 40 |
|
31 | | - const { form: formData, enhance } = form |
| 41 | + const { form: formData, enhance, errors, allErrors } = form |
| 42 | +
|
| 43 | + // name validation hidden form |
| 44 | + let nameServerError: string[] = [] |
| 45 | +
|
| 46 | + const { submit } = superForm( |
| 47 | + { name: '' }, |
| 48 | + { |
| 49 | + invalidateAll: false, |
| 50 | + applyAction: false, |
| 51 | + SPA: '?/check', |
| 52 | + onSubmit(event) { |
| 53 | + if (!$formData.name) { |
| 54 | + event.cancel() |
| 55 | + } |
| 56 | +
|
| 57 | + event.formData.set('name', $formData.name) |
| 58 | + }, |
| 59 | + onUpdated({ form }) { |
| 60 | + nameServerError = form.errors.name || [] |
| 61 | + $errors.name = [...nameServerError, ...($errors.name || [])] |
| 62 | + } |
| 63 | + } |
| 64 | + ) |
| 65 | + const checkProjectName = debounce(300, submit) |
32 | 66 | </script> |
33 | 67 |
|
34 | 68 | <Dialog.Root bind:open> |
|
39 | 73 | + Create Project |
40 | 74 | </Dialog.Trigger> |
41 | 75 | <Dialog.Content class="sm:max-w-[425px]"> |
42 | | - <form method="POST" use:enhance> |
| 76 | + <form method="POST" action="?/post" use:enhance> |
43 | 77 | <Dialog.Header> |
44 | 78 | <Dialog.Title>New Project</Dialog.Title> |
45 | 79 | <Dialog.Description> |
|
55 | 89 | data-testid="create-project-name-input" |
56 | 90 | placeholder="Enter Name" |
57 | 91 | bind:value={$formData.name} |
| 92 | + on:input={checkProjectName} |
58 | 93 | /> |
59 | 94 | </Form.Control> |
60 | 95 | <SlugDisplay name={$formData.name} /> |
|
74 | 109 | </Form.Field> |
75 | 110 | </div> |
76 | 111 | <Dialog.Footer> |
77 | | - <Form.Button data-testid="create-project-submit-button">Create Project</Form.Button> |
| 112 | + <Form.Button disabled={$allErrors.length !== 0} data-testid="create-project-submit-button"> |
| 113 | + Create Project |
| 114 | + </Form.Button> |
78 | 115 | </Dialog.Footer> |
79 | 116 | </form> |
80 | 117 | </Dialog.Content> |
|
0 commit comments