Skip to content

Commit ff23e22

Browse files
committed
Client-side validation didn't take refine into account a successful validation.
1 parent d30391b commit ff23e22

File tree

5 files changed

+141
-9
lines changed

5 files changed

+141
-9
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ Headlines: Added, Changed, Deprecated, Removed, Fixed, Security
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [Unreleased]
9+
10+
### Fixed
11+
12+
- Client-side validation didn't take refine into account a successful validation, not clearing all errors.
13+
814
## [1.6.0] - 2023-08-18
915

1016
### Fixed

src/lib/client/clientValidation.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -394,13 +394,8 @@ async function _validateField<T extends ZodValidation<AnyZodObject>, M>(
394394
Errors.update(updater);
395395
}
396396

397-
function Errors_clearFormLevelErrors() {
398-
Errors.update(($errors) => {
399-
traversePaths($errors, (path) => {
400-
if (path.key == '_errors') return path.set(undefined);
401-
});
402-
return $errors;
403-
});
397+
function Errors_clearAll() {
398+
clearErrors(Errors, { undefinePath: null, clearFormLevelErrors: true });
404399
}
405400

406401
function Errors_fromZod(
@@ -504,8 +499,7 @@ async function _validateField<T extends ZodValidation<AnyZodObject>, M>(
504499
errors: options.errors ?? current?.value
505500
};
506501
} else {
507-
// Clear form-level errors
508-
Errors_clearFormLevelErrors();
502+
Errors_clearAll();
509503
return { validated: true, errors: undefined };
510504
}
511505
} else {
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { superValidate, message } from '$lib/server';
2+
import { fail } from '@sveltejs/kit';
3+
4+
import { schema } from './schema';
5+
6+
///// Load function /////
7+
8+
export const load = async () => {
9+
const form = await superValidate(schema);
10+
return { form };
11+
};
12+
13+
///// Form actions /////
14+
15+
export const actions = {
16+
default: async ({ request }) => {
17+
const form = await superValidate(request, schema);
18+
19+
console.log('POST', form);
20+
21+
if (!form.valid) return fail(400, { form });
22+
23+
return message(form, 'Form posted successfully!');
24+
}
25+
};
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
<script lang="ts">
2+
import { page } from '$app/stores';
3+
import { superForm } from '$lib/client';
4+
import SuperDebug from '$lib/client/SuperDebug.svelte';
5+
import { schema } from './schema';
6+
7+
export let data;
8+
9+
const { form, errors, message, constraints, enhance, tainted } = superForm(
10+
data.form,
11+
{ validators: schema, taintedMessage: null }
12+
);
13+
</script>
14+
15+
<SuperDebug collapsible data={$tainted} />
16+
17+
<h3>Superforms testing ground</h3>
18+
19+
{#if $message}
20+
<div
21+
class="status"
22+
class:error={$page.status >= 400}
23+
class:success={$page.status == 200}
24+
>
25+
{$message}
26+
</div>
27+
{/if}
28+
29+
<form method="POST" use:enhance>
30+
<label>
31+
Name<br />
32+
<input
33+
name="name"
34+
aria-invalid={$errors.name ? 'true' : undefined}
35+
bind:value={$form.name}
36+
/>
37+
{#if $errors.name}<span class="invalid">{$errors.name}</span>{/if}
38+
</label>
39+
40+
<label>
41+
Second name<br />
42+
<input
43+
name="secondName"
44+
aria-invalid={$errors.secondName ? 'true' : undefined}
45+
bind:value={$form.secondName}
46+
/>
47+
{#if $errors.secondName}<span class="invalid">{$errors.secondName}</span
48+
>{/if}
49+
</label>
50+
51+
<button>Submit</button>
52+
</form>
53+
54+
<hr />
55+
<p>
56+
<a target="_blank" href="https://superforms.rocks/api">API Reference</a>
57+
</p>
58+
59+
<style>
60+
.invalid {
61+
color: red;
62+
}
63+
64+
.status {
65+
color: white;
66+
padding: 4px;
67+
padding-left: 8px;
68+
border-radius: 2px;
69+
font-weight: 500;
70+
}
71+
72+
.status.success {
73+
background-color: seagreen;
74+
}
75+
76+
.status.error {
77+
background-color: #ff2a02;
78+
}
79+
80+
input {
81+
background-color: #ddd;
82+
}
83+
84+
a {
85+
text-decoration: underline;
86+
}
87+
88+
hr {
89+
margin-top: 4rem;
90+
}
91+
92+
form {
93+
padding-top: 1rem;
94+
padding-bottom: 1rem;
95+
}
96+
</style>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { z } from 'zod';
2+
3+
export const schema = z
4+
.object({
5+
name: z.string().min(1),
6+
secondName: z.string().min(1)
7+
})
8+
.refine(({ name, secondName }) => name === secondName, {
9+
message: 'Names must be the same',
10+
path: ['secondName']
11+
});

0 commit comments

Comments
 (0)