Input
Renders all the inputs of the types listed at: W3schools Input Types and accepts as props any html attribute listed at: Html Input Attributes.
Props
type
: string
- Type listed at: W3schools Input Types.
name
: string
- A field's name in Usetheform state.
- If the Input is rendered within a
<Collection array />
, name is not allowed as prop.
index
: string
- A field's index in an array Collection.
- index is only allowed if your Input is rendered within a
<Collection array />
.
value
: string | number
- Specifies the initial value of an input element.
checked
: boolean
- Specifies whether an input element should be pre-selected or not (for type="checkbox" or type="radio").
touched
: boolean
- A field that has been touched/visited. Default value of false.
- If true, validation messages (sync and async) will be shown but only when the event onBlur of the field is triggered by a user action.
reducers
: array | function
(nextValue, prevValue, formState) => nextValue
- An array whose values correspond to different reducing functions.
- Reducer functions specify how the Input's value changes.
innerRef
: object (a mutable ref object)
- When you need to access the underlying DOM node created by an Input (e.g. to call focus), you can use a ref to store a reference to the input dom node.
const ref = useRef(null)
<Input innerRef={ref} type="text" name="test" />
Basic usage
import { Form, Input, Collection } from 'usetheform'
Preview
Live Editor
<Form> <Input type="text" name="name" value="foo" placeholder="Name" /> <div className="flex space-x-4"> <Input type="radio" name="gender" value="M" placeholder="M" /> <Input type="radio" name="gender" value="F" placeholder="F" /> <Input type="radio" name="gender" value="Other" placeholder="Other" /> </div> <div className="flex space-x-4"> <Input type="checkbox" name="option1" checked placeholder="Option 1" /> <Input type="checkbox" name="option2" placeholder="Option 2" /> </div> <Input type="file" name="file" /> </Form>
Reducers
import { Form, Input } from 'usetheform'
Preview
Live Editor
function InputWithReducers () { const prevNumberGreater10 = (nextValue, prevValue) => nextValue > 10 ? prevValue : nextValue; const prevNumberLessThan1 = (nextValue, prevValue) => nextValue <= 0 ? prevValue : nextValue; return ( <Form> <Input type="number" name="numberWithReducer" reducers={[prevNumberLessThan1, prevNumberGreater10]} placeholder="Number" value="1" /> </Form> ) }
Validation - Sync
import { Form, useValidation } from 'usetheform'
Preview
Live Editor
function FormSyncValidation() { const isValidEmail = value => !(value && !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+.[A-Z]{2,4}$/i.test(value)) ? undefined : "Mail not Valid"; const required = value => (value && value.trim() !== "" ? undefined : "Required"); const [status, validation] = useValidation([required, isValidEmail]); return ( <Form> <Input type="text" name="email" touched placeholder="Email" {...validation} /> {status.error && <label className="vl">{status.error}</label>} <Submit /> </Form> ) }
Validation - Async
import { Form, Input, useAsyncValidation } from 'usetheform';
Preview
Live Editor
function FormAsyncValidation() { const [asyncStatus, asyncValidation] = useAsyncValidation(asyncTestInput); return ( <Form> <Input type="text" name="username" touched placeholder="Username" {...asyncValidation} /> {asyncStatus.status === undefined && <label className="vl">Async Check Not Started Yet</label>} {asyncStatus.status === "asyncStart" && <label className="vl">Checking...</label>} {asyncStatus.status === "asyncError" && <label className="vl">{asyncStatus.value}</label>} {asyncStatus.status === "asyncSuccess" && <label className="vl">{asyncStatus.value}</label>} <br /> <Submit /> </Form> ) }
Detailed Explanation:
Submit.ts
import { useForm } from 'usetheform'
export const Submit = () => {
const { isValid } = useForm();
return (
<button disabled={!isValid} type="submit">
Submit
</button>
);
};
AsyncValidators.ts
export const asyncTestInput = value =>
new Promise((resolve, reject) => {
// it could be an API call or any async operation
setTimeout(() => {
if (value === "foo") {
reject("username already in use");
} else {
resolve("Success");
}
}, 1000);
});