Skip to content

Commit

Permalink
Fix nested fieldset linking (no deep cloning)
Browse files Browse the repository at this point in the history
  • Loading branch information
webblocksapp committed Feb 21, 2024
1 parent 2bf1958 commit 627c7a0
Show file tree
Hide file tree
Showing 4 changed files with 244 additions and 285 deletions.
@@ -0,0 +1,11 @@
import type { Meta } from 'storybook-solidjs';

import { NestedDeepFieldImpl } from '.';

const meta = {
component: NestedDeepFieldImpl,
} satisfies Meta<typeof NestedDeepFieldImpl>;

export default meta;

export const NestedDeepField = {};
@@ -0,0 +1,98 @@
import { useFormHandler } from '@hooks';
import { zodSchema } from '@adapters';
import { Component, For, Show } from 'solid-js';
import { z } from 'zod';
import { TextInput } from '@example-components';

const schema = z.object({
contacts: z
.array(
z.object({
name: z.object({
first: z.string().min(2, 'Minimum 2 characters'),
last: z.string().min(2, 'Minimum 2 characters'),
}),
email: z.string().email('Incorrect contact email'),
phone: z.string().min(5, 'Minimum 5 characters').optional().or(z.literal('')),
password: z.string().min(8, 'Minimum 8 characters').optional().or(z.literal('')),
createUser: z.boolean().default(false),
})
)
.min(1, 'There must be at least one (1) contact person for a client'),
});

export const NestedDeepFieldImpl: Component = () => {
const formHandler = useFormHandler(zodSchema(schema));
const { formData } = formHandler;

const submit = async (event: Event) => {
event.preventDefault();

try {
await formHandler.validateForm();
alert(`Data submitted \n ${JSON.stringify(formData())}`);
formHandler.resetForm();
} catch (error) {
console.error(error);
}
};

return (
<form autocomplete="off" onSubmit={submit}>
<h3 class="h2">Contacts</h3>
<section>
<ul>
<For each={formHandler.formData().contacts}>
{(contact, index) => (
<li>
<div class="col-span-2 flex w-full items-center justify-end gap-x-2">
{formHandler.formData().contacts.length > 1 && (
<div class="text-sm text-gray-400"># {index() + 1}</div>
)}
{index() > 0 && (
<button onClick={() => formHandler.removeFieldset(index(), 'contacts')}>Remove contact</button>
)}
</div>
<TextInput
label="First Name"
formHandler={formHandler}
autocomplete="off"
name={`contacts.${index()}.name.first`}
/>
<TextInput
label="Last Name"
formHandler={formHandler}
autocomplete="off"
name={`contacts.${index()}.name.last`}
/>
<TextInput
label="Email"
formHandler={formHandler}
autocomplete="off"
name={`contacts.${index()}.email`}
/>
<TextInput
label="Phone"
formHandler={formHandler}
autocomplete="off"
name={`contacts.${index()}.phone`}
/>
<Show when={contact.createUser}>
<TextInput
label="Password"
formHandler={formHandler}
autocomplete="off"
name={`contacts.${index()}.password`}
/>
</Show>
</li>
)}
</For>
</ul>
<button type="button" onClick={() => formHandler.addFieldset({ basePath: 'contacts' })}>
Add contact
</button>
</section>
</form>
);
};
3 changes: 1 addition & 2 deletions packages/lib/src/hooks/useFormHandler/index.ts
Expand Up @@ -986,8 +986,7 @@ export const useFormHandler = <T = any>(validationSchema: ValidationSchema<T>, o
? get<any[]>(formData.data, options.basePath).length
: (formData.data as unknown as any[]).length;
const builtPath = options?.basePath ? `${options?.basePath}.${length}` : `${length}`;
const data = { ...defaultData[0], ...getFieldDefaultValue(builtPath)[0] };

const data = clone({ ...defaultData[0], ...getFieldDefaultValue(builtPath)[0] });
setFieldData(builtPath, data);
addFieldsetState(builtPath, data);
validateFieldsets(options?.basePath);
Expand Down

0 comments on commit 627c7a0

Please sign in to comment.