Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions docs/src/components/navigation/docs_navigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,28 @@ export const DocsNavigation = () => {
reset
</Link>
</li>
<li>
<Link
href="/docs/create-form/set-error"
color={
location.pathname.includes("/docs/create-form/set-error") ? "accent" : "secondary"
}
>
setError
</Link>
</li>
<li>
<Link
href="/docs/create-form/clear-errors"
color={
location.pathname.includes("/docs/create-form/clear-errors")
? "accent"
: "secondary"
}
>
clearErrors
</Link>
</li>
<li>
<Link
href="/docs/create-form/set-value"
Expand Down
81 changes: 81 additions & 0 deletions docs/src/routes/docs/create-form/clear-errors.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { Title } from "@solidjs/meta";
import { Code } from "~/components/code/code";
import { Container } from "~/components/container/container";
import { DocsNavigation } from "~/components/navigation/docs_navigation";
import { Table } from "~/components/table/table";

const ClearErrors = () => {
return (
<main>
<Title>clearErrors - createForm</Title>
<Container.Grid>
<DocsNavigation />

<Container.Content>
<h1>clearErrors</h1>

<p>This function can manually clear errors in the form.</p>

<pre
style={{ color: "var(--colors-accent-500)", "white-space": "break-spaces" }}
>{`(name?: string | string[]) => void`}</pre>

<p style={{ "margin-bottom": 0 }}>Props</p>
<hr />

<Table>
{[
["Type", "Description", "Example"],
["undefined", "Remove all errors.", "clearErrors()"],
["string", "Remove single error.", 'clearErrors("email")'],
["string[]", "Remove multiple errors.", 'clearErrors(["email", "password"])']
]}
</Table>

<Code language="js">{`import { createForm } from "solid-hook-form"

export const ExampleForm = () => {
const form = useForm()
const {
register,
formState: { errors },
handleSubmit,
clearErrors
} = form

const onSubmit = (data) => {
console.log(data)
}

return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register("firstName", { required: true })} />
<input {...register("lastName", { required: true })} />
<input {...register("username", { required: true })} />

<button type="button" onClick={() => clearErrors("firstName")}>
Clear firstName errors
</button>

<button
type="button"
onClick={() => clearErrors(["firstName", "lastName"])}
>
Clear firstName and lastName errors
</button>

<button type="button" onClick={() => clearErrors()}>
Clear all errors
</button>

<button type="submit">Submit</button>
</form>
)
}`}</Code>
</Container.Content>
</Container.Grid>
</main>
);
};

export default ClearErrors;
10 changes: 10 additions & 0 deletions docs/src/routes/docs/create-form/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,16 @@ const ExampleForm = () => {
reset
</Link>
</li>
<li>
<Link href="/docs/create-form/set-error" color="accent">
setError
</Link>
</li>
<li>
<Link href="/docs/create-form/clear-errors" color="accent">
clearErrors
</Link>
</li>
<li>
<Link href="/docs/create-form/set-value" color="accent">
setValue
Expand Down
104 changes: 104 additions & 0 deletions docs/src/routes/docs/create-form/set-error.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import { Title } from "@solidjs/meta";
import { Code } from "~/components/code/code";
import { Container } from "~/components/container/container";
import { DocsNavigation } from "~/components/navigation/docs_navigation";
import { Table } from "~/components/table/table";

const SetError = () => {
return (
<main>
<Title>setError - createForm</Title>
<Container.Grid>
<DocsNavigation />

<Container.Content>
<h1>setError</h1>

<p>This function allows you to manually set one or more errors.</p>

<pre
style={{ color: "var(--colors-accent-500)", "white-space": "break-spaces" }}
>{`(name: string, error: FieldError, options?: SetErrorOptions) => void`}</pre>

<p style={{ "margin-bottom": 0 }}>Props</p>
<hr />

<Table>
{[
["Name", "Type", "Description"],
["name", "string", "Input's name."],
["error", "FieldError", "Set an error with its type and message."],
[
"options.shouldFocus",
"boolean",
"Should focus the input during setting an error. This only works when the input's reference is registered."
]
]}
</Table>

<p style={{ "margin-bottom": 0 }}>Rules</p>
<hr />

<ul>
<li>
This method will not persist the associated input error if the input passes register's
associated rules.
</li>
<li>
An error that is not associated with an input field will be persisted until cleared
with clearErrors.
</li>
<li>
Can be useful in the handleSubmit method when you want to give error feedback to a
user after async validation (for instance API returns validation errors).
</li>
</ul>

<Code language="js">{`import { createForm } from "solid-hook-form"

export const ExampleForm = () => {
const form = createForm({
defaultValues: {
email: ""
}
})
const { formState, register, handleSubmit, setError } = form
const { errors } = formState

const onSubmit = async (values) => {
const response = await fetch("/api/validate", {
method: "POST",
body: JSON.stringify(values)
})

if (response.status !== 200) {
setError("email", {
type: response.status.toString()
message: "This email is already in use"
})
}
}

return (
<form onSubmit={handleSubmit(onSubmit)}>
<label>Email</label>
<input
{...register("email")}
aria-invalid={Boolean(errors.email)}
/>

{errors.email && (
<p role="alert">{errors.email.message}</p>
)}

<button type="submit">Submit</button>
</form>
)
}`}</Code>
</Container.Content>
</Container.Grid>
</main>
);
};

export default SetError;
84 changes: 84 additions & 0 deletions docs/src/routes/examples/async-validation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/** biome-ignore-all lint/suspicious/noUselessEscapeInString: regex escape */

import { Title } from "@solidjs/meta";
import { Link } from "solid-uix";
import { Code } from "~/components/code/code";
import { Container } from "~/components/container/container";

const AsyncValidation = () => {
return (
<main>
<Title>Async Validation</Title>
<Container>
<h1>Async Validation</h1>

<p>
You can find full example at{" "}
<Link
href="https://stackblitz.com/edit/solidjs-templates-hrzxfhbq?file=src%2Fexample_form%2Fexample_form.tsx"
target="_blank"
color="accent"
>
StackBlitz
</Link>
.
</p>

<p>Set validation error manually after server response:</p>

<Code language="js">{`import { createForm } from 'solid-hook-form'
import { createSignal } from 'solid-js'

export const ExampleForm = () => {
const form = createForm({
defaultValues: {
email: ''
},
mode: 'onChange'
})
const {
errors,
register,
handleSubmit,
setError
} = form

const [isLoading, setIsLoading] = createSignal(false)

const onSubmit = (values: ExampleFormValues) => {
setIsLoading(true)

fetch('/api/validation')
.then(response => {
if (response.status !== 200) {
setError('email', {
type: 'custom',
message: 'This email is already in use'
})
}
})
.finally(() => {
setIsLoading(false)
})
}

return (
<form onSubmit={handleSubmit(onSubmit)}>
<label>Email</label>
<input {...register('email', { required: 'Required' })} />
{errors.email && <p role="alert">{errors.email.message}</p>}

{isLoading() && <p>Loading...</p>}

<Button type="submit" disabled={isLoading()}>
Save
</Button>
</form>
)
}`}</Code>
</Container>
</main>
);
};

export default AsyncValidation;
17 changes: 13 additions & 4 deletions docs/src/routes/examples/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { Title } from "@solidjs/meta";
import { Container } from "~/components/container/container";
import { Grid } from "~/components/grid/grid";
import check from "@phosphor-icons/core/regular/check-circle.svg?raw";
import curly from "@phosphor-icons/core/regular/brackets-curly.svg?raw";
import check from "@phosphor-icons/core/regular/check-circle.svg?raw";
// import server from "@phosphor-icons/core/regular/cloud-check.svg?raw";
import upload from "@phosphor-icons/core/regular/upload-simple.svg?raw";
import { Title } from "@solidjs/meta";
import { Container } from "~/components/container/container";
import { Footer } from "~/components/footer/footer";
import { Grid } from "~/components/grid/grid";

const Examples = () => {
return (
Expand Down Expand Up @@ -36,6 +37,14 @@ const Examples = () => {
<p>Integrate Yup schema validation into your form.</p>
</Grid.Item>

<Grid.Item href="/examples/async-validation">
<h2>
{/* <span innerHTML={server} /> */}
Async Validation
</h2>
<p>Give error feedback to a user after server-side validation.</p>
</Grid.Item>

<Grid.Item href="/examples/nested-values">
<h2>
<span innerHTML={curly} />
Expand Down