All Projects → bjjenson → react-useForm

bjjenson / react-useForm

Licence: other
World's simplest React hook to manage form state

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to react-useForm

Usetheform
React library for composing declarative forms, manage their state, handling their validation and much more.
Stars: ✭ 40 (+33.33%)
Mutual labels:  hooks, form, form-validation
React Hook Form
📋 React Hooks for form state management and validation (Web + React Native)
Stars: ✭ 24,831 (+82670%)
Mutual labels:  hooks, form, form-validation
react-cool-form
😎 📋 React hooks for forms state and validation, less code more performant.
Stars: ✭ 246 (+720%)
Mutual labels:  hooks, form, form-validation
Resolvers
📋 Validation resolvers: Zod, Yup, Joi, Superstruct, and Vest.
Stars: ✭ 222 (+640%)
Mutual labels:  hooks, form, form-validation
Formik
Build forms in React, without the tears 😭
Stars: ✭ 29,047 (+96723.33%)
Mutual labels:  hooks, form
stook
A minimalist design state management library for React.
Stars: ✭ 86 (+186.67%)
Mutual labels:  hooks, form
Use Form
Build great forms without effort. 🚀
Stars: ✭ 42 (+40%)
Mutual labels:  hooks, form-validation
React Form
⚛️ Hooks for managing form state and validation in React
Stars: ✭ 2,270 (+7466.67%)
Mutual labels:  hooks, form
Form bloc
🔥 Dart and Flutter Package 🔥 Easy Form State Management using BLoC pattern 🔥 Wizard/stepper forms, asynchronous validation, dynamic and conditional fields, submission progress, serialization and more! 🔥
Stars: ✭ 239 (+696.67%)
Mutual labels:  form, form-validation
Formium
The headless form builder for the modern web.
Stars: ✭ 78 (+160%)
Mutual labels:  hooks, form
antd-react-form-builder
Example
Stars: ✭ 74 (+146.67%)
Mutual labels:  form, form-validation
FrontendForms
A module for ProcessWire CMS to create and validate forms on the frontend easily using the Valitron library.
Stars: ✭ 0 (-100%)
Mutual labels:  form, form-validation
React Hooks Helper
A custom React Hooks library that gives you custom hooks for your code.
Stars: ✭ 227 (+656.67%)
Mutual labels:  hooks, form
react-inputs-validation
A react component for form inputs validation. Online demo examples
Stars: ✭ 48 (+60%)
Mutual labels:  form, form-validation
Final Form
🏁 Framework agnostic, high performance, subscription-based form state management
Stars: ✭ 2,787 (+9190%)
Mutual labels:  form, form-validation
Fielder
A field-first form library for React and React Native
Stars: ✭ 160 (+433.33%)
Mutual labels:  hooks, form
Elm Form
Dynamic forms handling in Elm
Stars: ✭ 189 (+530%)
Mutual labels:  form, form-validation
Material Singleinputform
A single EditText instead of a classical form. Library that implements flavienlaurent's singleinputform
Stars: ✭ 202 (+573.33%)
Mutual labels:  form, form-validation
ember-validity-modifier
Ember Octane addon to add custom validity (form validation) to form fields
Stars: ✭ 28 (-6.67%)
Mutual labels:  form, form-validation
ATGValidator
iOS validation framework with form validation support
Stars: ✭ 51 (+70%)
Mutual labels:  form, form-validation

react-hooks-useform

react-hooks-useform implements React hooks to enable an complete, lightweight form implementation for React. It works best with Material-UI components but can be used with native react inputs as well.

Installation

npm install --save react-hooks-useform

yarn add react-hooks-useform

Documentation

const [fieldProps, formProps] = useForm(formConfiguration)

formConfiguration

Prop Type Required Description
fields Array Yes Array of objects describing fieldConfiguration (see fieldConfiguration)
submit Function Yes (values)=>void Function calls when submit is triggered on form.
validate Function or Function[] No Called each time the form validates
initialValues Map<String, any> No Values to populate form fields. Can be lazy loaded.
options FormOptions No optional configurations

fieldConfiguration

Prop Type Required Description
name String Yes Name of the field. Will be used to pull data from initialValues.
type FieldTypes No Type of field data (text,boolean,select,number)
helperText String No Helper/Error text associated with the field
optional Boolean No Specifies if the field is optional or required for field validation
requiredMessage String No Message to display when required field validation fails (Defaults to 'Required')
label String No Label to display with the field
normalize Function No Normlalization function during onChange event to normalize data such as numbers/phones etc.
value any No Initial value used by the field (default: "")
validate (value: T, fieldName: String, getValues: () => IValues) => String No Validation function for field level validation. Can be combined with Form level validation.
options Array No Pass through options if type is select
valueFromChange (event: Object) => T No Helper function used if onChange handler needs to provide a value other than event.target.value

fieldProps Object

Prop Type Description
error Boolean True if error exists on field, otherwise false
helperText String Helper or error text
label String Label provided by fieldConfiguration, Formatted as ${label} (optional) if field configured as an optional field. This can be customized in FormOptions
value any Controlled value of the field
onBlur Function Event triggered upon input blur
onChange Function Event triggered upon input change

formProps Object

Prop Type Description
Form React.Component Component used to wrap the form inputs
submit Function Function to invoke when form should be submitted. Will trigger validation and if successful, trigger formConfiguration.submit
addField (field: fieldConfiguration) => void Call to add a new field dynamically to the form
removeField (fieldName: String) => void Call to remove a field dynamically form the form

fieldConfiguration

Prop Type Required Description
optionalLabelFormatter (label: String) => String No Function invoked to format labels for fields that are configured as optional

Examples

The following examples utilize Material-UI inputs

Simple Form

const SimpleForm = () => {
  const [fields, form] = useForm({
    fields: [
      { name: 'fullName', label: 'Full Name' },
      { name: 'nickname', label: 'Nickname' },
    ],
  })

  return (
    <form.Form>
      <Flexbox flexDirection='column'>
        <TextField {...fields.fullName} />
        <TextField {...fields.nickname} />
      </Flexbox>
      <Button type='submit' onClick={form.submit}>Submit</Button>
    </form.Form>
  )
}

export { SimpleForm }

Optional Fields

const SimpleFormOptionalFields = () => {
  const [fields, form] = useForm({
    fields: [
      { name: 'fullName', label: 'Full Name' },
      { name: 'nickname', label: 'Nickname', optional: true },
    ],
  })

  return (
    <form.Form>
      <Flexbox flexDirection='column'>
        <TextField {...fields.fullName} />
        <TextField {...fields.nickname} />
      </Flexbox>
      <Button type='submit' onClick={form.submit}>Submit</Button>
    </form.Form>
  )
}

export { SimpleFormOptionalFields }

Customize optional field prompt

const CustomizeOptionalPrompt = () => {
  const [fields, form] = useForm({
    fields: [
      { name: 'fullName', label: 'Full Name' },
      { name: 'nickname', label: 'Nickname', optional: true },
    ],
    options: {
      optionalLabelFormatter: label => `${label} - not required`,
    },
  })

  return (
    <form.Form>
      <Flexbox flexDirection='column'>
        <TextField {...fields.fullName} />
        <TextField {...fields.nickname} />
      </Flexbox>
      <Button type='submit' onClick={form.submit}>Submit</Button>
    </form.Form>
  )
}

export { CustomizeOptionalPrompt }

Field level validation

const FieldValidation = () => {
  const [fields, form] = useForm({
    fields: [
      { name: 'fullName', label: 'Full Name' },
      { name: 'nickname', label: 'Nickname', optional: true },
      { name: 'phone', label: 'Phone', validate: validatePhone },
    ],
  })

  return (
    <form.Form>
      <Flexbox flexDirection='column'>
        <TextField {...fields.fullName} />
        <TextField {...fields.nickname} />
        <TextField {...fields.phone} />
      </Flexbox>
      <Button type='submit' onClick={form.submit}>Submit</Button>
    </form.Form>
  )
}

export { FieldValidation }

Field input normalize

const normalizePhone = input => {
  let normalizedPhone
  ...
  return normalizedPhone
}

const FieldNormalize = () => {
  const [fields, form] = useForm({
    fields: [
      { name: 'fullName', label: 'Full Name' },
      { name: 'nickname', label: 'Nickname', optional: true },
      { name: 'phone', label: 'Phone', validate: validatePhone, normalize: normalizePhone },
    ],
  })

  return (
    <form.Form>
      <Flexbox flexDirection='column'>
        <TextField {...fields.fullName} />
        <TextField {...fields.nickname} />
        <TextField {...fields.phone} />
      </Flexbox>
      <Button type='submit' onClick={form.submit}>Submit</Button>
    </form.Form>
  )
}

export { FieldNormalize }

Custom helper text

const HelperText = () => {
  const [fields, form] = useForm({
    fields: [
      { name: 'fullName', label: 'Full Name' },
      { name: 'nickname', label: 'Nickname', optional: true },
      { name: 'phone', label: 'Phone', helperText: 'Please enter a phone number' },
    ],
  })

  return (
    <form.Form>
      <Flexbox flexDirection='column'>
        <TextField {...fields.fullName} />
        <TextField {...fields.nickname} />
        <TextField {...fields.phone} />
      </Flexbox>
      <Button type='submit' onClick={form.submit}>Submit</Button>
    </form.Form>
  )
}

export { HelperText }

Custom required field message

const CustomRequiredMessage = () => {
  const [fields, form] = useForm({
    fields: [
      { name: 'fullName', label: 'Full Name', requiredMessage: 'Name is Required' },
      { name: 'nickname', label: 'Nickname', optional: true },
      { name: 'phone', label: 'Phone', requiredMessage: 'Phone is Required' },
    ],
  })

  return (
    <form.Form>
      <Flexbox flexDirection='column'>
        <TextField {...fields.fullName} />
        <TextField {...fields.nickname} />
        <TextField {...fields.phone} />
      </Flexbox>
      <Button type='submit' onClick={form.submit}>Submit</Button>
    </form.Form>
  )
}

export { CustomRequiredMessage }

Boolean field

const BooleanToggle = () => {
  const SwitchField = ({ label, error, helperText, ...rest }) => {
    return (
      <FormControlLabel
        control={(
          <Switch
            {...rest}
          />
        )}
        label={label}
      />
    )
  }

  const [fields, form] = useForm({
    fields: [
      { name: 'fullName', label: 'Full Name' },
      { name: 'nickname', label: 'Nickname' },
      { name: 'isAdmin', label: 'Administrator', type: 'boolean' },
    ],
  })

  return (
    <form.Form>
      <Flexbox flexDirection='column'>
        <TextField {...fields.fullName} />
        <TextField {...fields.nickname} />
        <SwitchField {...fields.isAdmin} />
      </Flexbox>
      <Button type='submit' onClick={form.submit}>Submit</Button>
    </form.Form>
  )
}

export { BooleanToggle }

Number field

const NumberField = () => {
  const [fields, form] = useForm({
    fields: [
      { name: 'fullName', label: 'Full Name' },
      { name: 'nickname', label: 'Nickname' },
      { name: 'age', label: 'Age', type: 'number', normalize: normalizeNumber },
    ],
  })

  return (
    <form.Form>
      <Flexbox flexDirection='column'>
        <TextField {...fields.fullName} />
        <TextField {...fields.nickname} />
        <TextField {...fields.age} />
      </Flexbox>
      <Button type='submit' onClick={form.submit}>Submit</Button>
    </form.Form>
  )
}

export { NumberField }

Select field

const SelectField = () => {
  const SelectComponent = ({
    label,
    error,
    value,
    helperText,
    children,
    options,
    ...rest
  }) => {

    return (
      <FormControl>
        {label && <InputLabel error={error}>{label}</InputLabel>}
        <Select
          value={value}
          {...rest}
          error={error}
        >
          {options.map((option) => {
            return <MenuItem key={options.value} value={option.value}>{option.label}</MenuItem>
          })}
        </Select>
        <FormHelperText error={error}>{helperText}</FormHelperText>
      </FormControl>
    )
  }

  const genderOptions = [
    { value: 'male', label: 'Male' },
    { value: 'female', label: 'Female' },
  ]

  const [fields, form] = useForm({
    fields: [
      { name: 'fullName', label: 'Full Name' },
      { name: 'nickname', label: 'Nickname' },
      { name: 'gender', label: 'Gender', type: 'select', options: genderOptions },
    ],
  })

  return (
    <form.Form>
      <Flexbox flexDirection='column'>
        <TextField {...fields.fullName} />
        <TextField {...fields.nickname} />
        <SelectComponent {...fields.gender} />
      </Flexbox>
      <Button type='submit' onClick={form.submit}>Submit</Button>
    </form.Form>
  )
}

export { SelectField }

Initial values passed into form

const InitialValuesSet = ({ initialValues }) => {
  const [fields, form] = useForm({
    fields: [
      { name: 'fullName', label: 'Full Name' },
      { name: 'nickname', label: 'Nickname' },
    ],
    initialValues,
  })

  return (
    <form.Form>
      <Flexbox flexDirection='column'>
        <TextField {...fields.fullName} />
        <TextField {...fields.nickname} />
      </Flexbox>
      <Button type='submit' onClick={form.submit}>Submit</Button>
    </form.Form>
  )
}

export { InitialValuesSet }

Dynamic fields

const DynamicFields = () => {

  const [fields, form] = useForm({
    fields: [
      { name: 'fullName', label: 'Full Name' },
      { name: 'nickname', label: 'Nickname' },
    ],
  })

  const [dynamicFields, dynamicForm] = useForm({
    fields: [
      { name: 'name', label: 'Name' },
      { name: 'label', label: 'Label' },
    ],
    submit: values => {
      const name = values.get('name')
      const label = values.get('label')
      form.addField({ name, label })
    },
  })

  return (
    <Flexbox flexDirection='column'>
      <dynamicForm.Form>
        <Flexbox>
          <TextField {...dynamicFields.name} />
          <TextField {...dynamicFields.label} />
          <Button type='submit' onClick={dynamicForm.submit}>Add Field</Button>
        </Flexbox>
      </dynamicForm.Form>
      <Divider style={{ margin: '24px 16px 8px 16px' }} />
      <form.Form>
        <Flexbox flexDirection='column'>
          <TextField {...fields.fullName} />
          <TextField {...fields.nickname} />
          {Object.keys(fields)
            .filter(key => (key !== 'fullName' && key !== 'nickname'))
            .map(key => (
              <Flexbox key={key}>
                <TextField {...fields[key]} />
                <Button onClick={() => form.removeField(key)}>X</Button>
              </Flexbox>
            ))
          }
        </Flexbox>
        <Button type='submit' onClick={form.submit}>Submit</Button>
      </form.Form>
    </Flexbox>
  )
}

export { DynamicFields }
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].