Skip to main content

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

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);
});