Skip to content

Commit 39eb344

Browse files
committed
form.set should support setting multiple values
1 parent ba6c312 commit 39eb344

File tree

3 files changed

+93
-13
lines changed

3 files changed

+93
-13
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@programmer_network/use-ajv-form",
3-
"version": "1.0.11",
3+
"version": "1.0.12",
44
"description": "Custom React Hook that integrates with Ajv JSON Schema Validator",
55
"main": "dist/use-ajv-form.es.js",
66
"author": "Aleksandar Grbic",

src/index.ts

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -78,18 +78,24 @@ const useAJVForm = <T extends Record<string, any>>(
7878

7979
const setFormState = (form: Partial<FormField<T>>) => {
8080
setState((current) => {
81-
const name = Object.keys(form)[0] as keyof T;
82-
const state = { ...current };
83-
state[name] = {
84-
...state[name],
85-
value: getValue(form[name]),
86-
error: state[name]?.error || '',
87-
};
81+
const newState = { ...current };
82+
83+
Object.keys(form).forEach((key) => {
84+
const name = key as keyof T;
85+
newState[name] = {
86+
...newState[name],
87+
value: getValue(form[name]),
88+
error: newState[name]?.error || '',
89+
};
90+
});
8891

89-
setCurrentField({ name, editId: editCounter });
92+
setCurrentField({
93+
name: Object.keys(form)[0] as keyof T,
94+
editId: editCounter,
95+
});
9096
setEditCounter(editCounter + 1);
9197

92-
return state;
98+
return newState;
9399
});
94100
};
95101

src/useAjvForm.test.tsx

Lines changed: 77 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,7 @@ describe('useAJVForm', () => {
102102

103103
const { result } = renderHook(() => useAJVForm(initialData, schema));
104104

105-
act(() => {
106-
result.current.set({ title: 'New Title' });
107-
});
105+
result.current.set({ title: 'New Title' });
108106

109107
result.current.reset();
110108

@@ -367,3 +365,79 @@ describe('useAJVForm', () => {
367365
expect(result.current.isValid).toBe(true);
368366
});
369367
});
368+
369+
describe('useAJVForm with multiple field updates', () => {
370+
it('updates multiple fields at once', () => {
371+
const initialData = { title: '', description: '' };
372+
const schema: JSONSchemaType<{ title: string; description: string }> = {
373+
type: 'object',
374+
required: ['title', 'description'],
375+
properties: {
376+
title: { type: 'string' },
377+
description: { type: 'string' },
378+
},
379+
};
380+
381+
const { result } = renderHook(() => useAJVForm(initialData, schema));
382+
383+
result.current.set({ title: 'New Title', description: 'New Description' });
384+
385+
expect(result.current.state.title.value).toBe('New Title');
386+
expect(result.current.state.description.value).toBe('New Description');
387+
});
388+
389+
it('preserves existing error messages when updating multiple fields', () => {
390+
const initialData = { title: '', description: '' };
391+
const schema: JSONSchemaType<{ title: string; description: string }> = {
392+
type: 'object',
393+
required: ['title', 'description'],
394+
properties: {
395+
title: { type: 'string', minLength: 3 },
396+
description: { type: 'string', minLength: 3 },
397+
},
398+
};
399+
400+
const { result } = renderHook(() => useAJVForm(initialData, schema));
401+
402+
result.current.set({ title: 'Ti', description: 'De' });
403+
result.current.onBlur('title');
404+
result.current.onBlur('description');
405+
406+
expect(result.current.state.title.error).not.toBe('');
407+
expect(result.current.state.description.error).not.toBe('');
408+
409+
expect(result.current.state.title.error).toBe(
410+
'Should be at least 3 characters long.',
411+
);
412+
expect(result.current.state.description.error).toBe(
413+
'Should be at least 3 characters long.',
414+
);
415+
});
416+
417+
it('correctly updates isDirty when multiple fields are changed', () => {
418+
const initialData = {
419+
title: 'Original Title',
420+
description: 'Original Description',
421+
};
422+
const schema: JSONSchemaType<{ title: string; description: string }> = {
423+
type: 'object',
424+
required: ['title', 'description'],
425+
properties: {
426+
title: { type: 'string' },
427+
description: { type: 'string' },
428+
},
429+
};
430+
431+
const { result } = renderHook(() => useAJVForm(initialData, schema));
432+
433+
result.current.set({
434+
title: 'Changed Title',
435+
description: 'Changed Description',
436+
});
437+
438+
expect(result.current.isDirty).toBe(true);
439+
});
440+
441+
// Additional tests can be written to cover other scenarios such as validation,
442+
// resetting the form, handling errors, etc., when multiple fields are involved.
443+
});

0 commit comments

Comments
 (0)