Skip to content

Commit 12de039

Browse files
committed
Schema transformations weren't updating the form data on the client.
1 parent 566fef3 commit 12de039

File tree

4 files changed

+61
-18
lines changed

4 files changed

+61
-18
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1010
### Fixed
1111

1212
- Tainted fields were set to undefined when not needed, unnecessarily triggering client-side validation.
13+
- Schema transformations weren't updating the form data on the client. ([#298](https://github.com/ciscoheat/sveltekit-superforms/issues/298))
1314

1415
## [1.11.0] - 2023-11-28
1516

src/lib/client/clientValidation.ts

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ async function _clientValidation<T extends AnyZodObject, M = unknown>(
224224
*/
225225
export async function validateObjectErrors<T extends AnyZodObject, M>(
226226
formOptions: FormOptions<T, M>,
227-
data: z.infer<T>,
227+
Form: SuperForm<T, M>['form'],
228228
Errors: SuperForm<T, M>['errors'],
229229
tainted: TaintedFields<UnwrapEffects<T>> | undefined
230230
) {
@@ -236,7 +236,7 @@ export async function validateObjectErrors<T extends AnyZodObject, M>(
236236
}
237237

238238
const validators = formOptions.validators as AnyZodObject;
239-
const result = await validators.safeParseAsync(data);
239+
const result = await validators.safeParseAsync(get(Form));
240240

241241
if (!result.success) {
242242
const newErrors = mapErrors(
@@ -281,13 +281,15 @@ export async function validateObjectErrors<T extends AnyZodObject, M>(
281281
});
282282
return currentErrors;
283283
});
284+
// Disable if form values shouldn't be updated immediately:
285+
if (result.data) Form.set(result.data);
284286
}
285287
}
286288

287289
type ValidationResult<T extends ZodValidation<AnyZodObject>> = {
288290
validated: boolean | 'all';
289291
errors: string[] | undefined;
290-
data: SuperForm<T, unknown>['form'] | undefined;
292+
data: z.infer<T> | undefined;
291293
};
292294

293295
/**
@@ -344,7 +346,7 @@ export async function validateField<
344346
return errorMsgs ?? undefined;
345347
}
346348

347-
const errors = await _validateField(
349+
const result = await _validateField(
348350
path,
349351
formOptions.validators,
350352
data,
@@ -353,25 +355,25 @@ export async function validateField<
353355
options
354356
);
355357

356-
if (errors.validated) {
357-
if (errors.validated === 'all' && !errors.errors) {
358+
if (result.validated) {
359+
if (result.validated === 'all' && !result.errors) {
358360
// We validated the whole data structure, so clear all errors on success after delayed validators.
359361
// it will also set the current path to undefined, so it can be used in
360362
// the tainted+error check in oninput.
361363
Errors_clear();
362364
} else {
363-
errors.errors = Errors_update(errors.errors);
364-
return errors;
365+
result.errors = Errors_update(result.errors);
365366
}
366367
} else if (
367-
errors.validated === false &&
368+
result.validated === false &&
368369
formOptions.defaultValidator == 'clear'
369370
) {
370-
errors.errors = Errors_update(errors.errors);
371-
return errors;
371+
result.errors = Errors_update(result.errors);
372372
}
373373

374-
return errors;
374+
if (result.data) data.set(result.data, options);
375+
376+
return result;
375377
}
376378

377379
// @DCI-context

src/lib/client/index.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -749,12 +749,7 @@ export function superForm<
749749
updated = updated || (await Tainted__validate(path, taintOptions));
750750
}
751751
if (!updated) {
752-
await validateObjectErrors(
753-
options,
754-
get(Form),
755-
Errors,
756-
get(Tainted)
757-
);
752+
await validateObjectErrors(options, Form, Errors, get(Tainted));
758753
}
759754
}
760755
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<script lang="ts">
2+
import { z } from 'zod';
3+
import { superForm as _superForm } from '$lib/client';
4+
import { superValidateSync } from '$lib/client';
5+
import SuperDebug from '$lib/client/SuperDebug.svelte';
6+
7+
export const timePatternSchema = z.object({
8+
recurrenceRuleSets: z
9+
.object({
10+
endType: z.enum(['never', 'date', 'after']),
11+
rrule: z.string()
12+
})
13+
.transform((value) => {
14+
let newRrule = 'after';
15+
console.log({ ...value, rrule: newRrule });
16+
return { ...value, rrule: newRrule };
17+
})
18+
});
19+
20+
const superForm = _superForm(superValidateSync(timePatternSchema), {
21+
SPA: true,
22+
dataType: 'json',
23+
validators: timePatternSchema,
24+
taintedMessage: null
25+
});
26+
27+
$: ({ form } = superForm);
28+
</script>
29+
30+
<SuperDebug data={$form} />
31+
32+
<form use:superForm.enhance method="post">
33+
{#each ['never', 'date', 'after'] as item}
34+
<div>
35+
<input
36+
value={item}
37+
bind:group={$form.recurrenceRuleSets.endType}
38+
type="radio"
39+
id={item}
40+
name={item}
41+
/>
42+
{item}
43+
</div>
44+
{/each}
45+
</form>

0 commit comments

Comments
 (0)