Validate
The <Validate/> component is your primary method of validating form state, it builds in some key features to make sure maintain a good user experience around validation
The Validate component will only call your validate function when:
- the field loses focus
the user attempts to submit the form
or the validate function last returned a validation error (in which case the validate function will be called on each field change until the validation error is resolved)
This helps ensures that the Validate components will reprimand the user as little as possible
<Form onSubmit={alert}> <Label prop="email" label="Email"> <Input type="email" placeholder="john@snow.com"> <Validate invalid={(email) => !email?.includes("@")}> Email must include @ </Validate> <Validate invalid={(email) => !email?.split("@")[1]?.length}> Email must have text after the @ </Validate> <Validations /> </Input> </Label> <Submit /></Form>Nested validation
The <Validate/> uses the same Path system as the rest of the form framework. Meaning you can validate deeply nested fields by adding a prop='fieldName' to the component
<Form onSubmit={alert}> <Group prop="user"> <Label prop="email" label="Email"> <Input type="email" placeholder="john@snow.com" /> </Label> <Validate prop="email" invalid={(email) => !email?.includes("@")}> Email must include @ </Validate> </Group> <Validate prop="user/email" invalid={(email) => !email?.split("@")[1]?.length} > Email must have text after the @ </Validate> <Validations prop="user/email" /> <Submit /></Form>Complex validation
The <Validate/> can be passed an onSelect prop to validate based on any part of form state.
import { shallowEqualArray } from "@selkt/core"const keys = ["a", "b", "c"] render( <Form onSubmit={alert}> {keys.map((key) => { const label = key.toUpperCase() return ( <Label prop={key} label={label} key={key}> <Input /> <Validate select={(state) => { let result = [state[key]] for (let k of keys) { if (k === key) continue result.push(state[k]) } return result }} invalid={([value, ...rest]) => rest.includes(value)} equalityCheck={shallowEqualArray} > Input {label} must be unique </Validate> <Validations /> </Label> ) })} <Submit /> </Form>)Only validate on submit
Form can be passed a config object. In this demo we are setting the default to not validate on blur, and then conditionally adding it back to individual validate components
import { shallowEqualArray } from "@selkt/core"const keys = ["a", "b", "c"] render( <Form onSubmit={alert} config={{ validateOnBlur: false }}> <Label prop="a" label="Only validate on blur"> <Input /> <Validate required>Required</Validate> <Validate invalid={(v) => v && v.length < 8} validateOnBlur> Must be at least 8 characters </Validate> <Validations /> </Label> <Log /> <Submit /> </Form>)