Skip to content

Commit 8e1b308

Browse files
committed
onChange updates.
1 parent 163d5dc commit 8e1b308

File tree

6 files changed

+55
-16
lines changed

6 files changed

+55
-16
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Added
1111

12+
- `get` and `set` accessor for `onChange`.
1213
- `submit` method for `superForm`, a convenience instead of using [requestSubmit](https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/requestSubmit). Requires `use:enhance` or that a `HTMLElement` inside the form is passed as an argument.
1314

1415
### Fixed
1516

17+
- Type for `onChange.paths` wasn't strongly typed to `FormPath`.
1618
- Initial data was dereferenced after calling `superForm`, so it wasn't possible to update it when using `reset`.
1719

1820
## [2.4.0] - 2024-02-20

src/lib/client/proxies.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import type { FormPathArrays } from '../stringPath.js';
77
import type { SuperForm, TaintOption } from './index.js';
88
import type { Prettify } from '$lib/utils.js';
99

10-
type ProxyOptions = {
10+
export type ProxyOptions = {
1111
taint?: TaintOption;
1212
};
1313

src/lib/client/superForm.ts

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import type {
3737
ValidationResult
3838
} from '$lib/adapters/adapters.js';
3939
import type { InputConstraints } from '$lib/jsonSchema/constraints.js';
40+
import { fieldProxy, type ProxyOptions } from './proxies.js';
4041

4142
export type SuperFormEvents<T extends Record<string, unknown>, M> = Pick<
4243
FormOptions<T, M>,
@@ -126,7 +127,7 @@ export type FormOptions<
126127
error: App.Error;
127128
};
128129
}) => MaybePromise<unknown | void>);
129-
onChange: (event: ChangeEvent) => void;
130+
onChange: (event: ChangeEvent<T>) => void;
130131

131132
dataType: 'form' | 'json';
132133
jsonChunkSize: number;
@@ -276,16 +277,28 @@ type ValidationResponse<
276277
Invalid extends Record<string, unknown> | undefined = Record<string, any>
277278
> = { result: ActionResult<Success, Invalid> };
278279

279-
export type ChangeEvent =
280+
export type ChangeEvent<T extends Record<string, unknown>> =
280281
| {
281-
path: string;
282-
paths: string[];
282+
path: FormPath<T>;
283+
paths: FormPath<T>[];
283284
formElement: HTMLFormElement;
284285
target: Element;
286+
set: <Path extends FormPath<T>>(
287+
path: Path,
288+
value: FormPathType<T, Path>,
289+
options?: ProxyOptions
290+
) => void;
291+
get: <Path extends FormPath<T>>(path: Path) => FormPathType<T, Path>;
285292
}
286293
| {
287294
target: undefined;
288-
paths: string[];
295+
paths: FormPath<T>[];
296+
set: <Path extends FormPath<T>>(
297+
path: Path,
298+
value: FormPathType<T, Path>,
299+
options?: ProxyOptions
300+
) => void;
301+
get: <Path extends FormPath<T>>(path: Path) => FormPathType<T, Path>;
289302
};
290303

291304
type FullChangeEvent = {
@@ -661,8 +674,8 @@ export function superForm<
661674
function Form__changeEvent(event: FullChangeEvent) {
662675
if (!options.onChange || !event.paths.length || event.type == 'blur') return;
663676

664-
let changeEvent: ChangeEvent;
665-
const paths = event.paths.map(mergePath);
677+
let changeEvent: ChangeEvent<T>;
678+
const paths = event.paths.map(mergePath) as FormPath<T>[];
666679

667680
if (
668681
event.type &&
@@ -674,12 +687,26 @@ export function superForm<
674687
path: paths[0],
675688
paths,
676689
formElement: event.formElement,
677-
target: event.target
690+
target: event.target,
691+
set(path, value, options?) {
692+
// Casting trick to make it think it's a SuperForm
693+
fieldProxy({ form: Form } as SuperForm<T>, path, options).set(value);
694+
},
695+
get(path) {
696+
return get(fieldProxy(Form, path));
697+
}
678698
};
679699
} else {
680700
changeEvent = {
681701
paths,
682-
target: undefined
702+
target: undefined,
703+
set(path, value, options?) {
704+
// Casting trick to make it think it's a SuperForm
705+
fieldProxy({ form: Form } as SuperForm<T>, path, options).set(value);
706+
},
707+
get(path) {
708+
return get(fieldProxy(Form, path));
709+
}
683710
};
684711
}
685712

src/routes/(v2)/v2/issue-337-checkboxes/+page.svelte

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,23 @@
22
import { superForm } from '$lib/client/index.js';
33
import SuperDebug from '$lib/client/SuperDebug.svelte';
44
import CheckBox from './CheckBox.svelte';
5-
//import { zod } from '$lib/adapters/zod.js'
6-
//import { schema } from './schema.js';
75
86
export let data;
97
108
const theForm = superForm(data.form, {
119
taintedMessage: false,
12-
onChange({ paths }) {
10+
onChange({ paths, set, get }) {
11+
for (const path of paths) {
12+
if (path == 'accept') {
13+
set('extra', 12, { taint: false });
14+
} else if (path == 'extra') {
15+
if (get(path) == 12) {
16+
set('extra', 123, { taint: false });
17+
}
18+
}
19+
}
1320
console.log(paths);
1421
}
15-
//dataType: 'json',
1622
});
1723
1824
const { form, errors, tainted, message, enhance } = theForm;
@@ -22,6 +28,10 @@
2228

2329
{#if $message}<h4>{$message}</h4>{/if}
2430

31+
<p>Extra:{$form.extra}</p>
32+
33+
<p>Tainted:{Boolean($tainted?.extra)}</p>
34+
2535
<form method="POST" use:enhance>
2636
<div>Accept: <CheckBox form={theForm} field="accept" /></div>
2737
<div>
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { z } from 'zod';
22

33
export const schema = z.object({
4-
accept: z.boolean()
4+
accept: z.boolean(),
5+
extra: z.number().positive().optional().default(0)
56
});

src/tests/superValidate.test.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,6 @@ const simpleConstraints = {
132132
tags: {
133133
required: true
134134
}
135-
// TODO: extra should be required here too
136135
};
137136

138137
const nospacePattern = /^\S*$/;

0 commit comments

Comments
 (0)