2.1.0 • Published 9 months ago

formash v2.1.0

Weekly downloads
-
License
MIT
Repository
github
Last release
9 months ago

Formash

Formash is a simple React form library that uses hooks and schema to manage form state, errors, validation and so much more. Now you don't need to write a lot of code to manage your forms. You Just need to write a schema, pass it to the useForm hook and render your formSchema. and you are good to go. It is designed to be flexible and easy to use. You can use it with any UI library.

Installation

npm

npm i formash

yarn

yarn add formash

Usage

Formash provides the useForm hook, which takes a form schema as an argument and returns an object with various properties and functions to manage form state. Here's an overview of the available variables and functions:

formSchema

The formSchema is an array of objects that define the form fields. Each object represents a form field and contains properties such as name, type, error, value, and more. You can use the formSchema to render the form fields in your React components. Here are the available properties for each schema object:

PropertyTypeDescription
type (required)stringThe type of the input field (e.g., 'text', 'select', 'checkbox').
name (required)stringThe name of the input field.
idstringThe ID of the input field.
requiredbooleanIndicates whether the input field is required.
placeholderstringThe placeholder text for the input field.
classNamestringThe CSS class name for the input field.
styleReact.CSSPropertiesThe inline style for the input field.
labelstringThe label text for the input field.
labelClassNamestringThe CSS class name for the label element.
textstringAdditional text to display with the input field.
textClassNamestringThe CSS class name for the additional text element.
iconstringThe name of the icon to display with the input field.
iconClassNamestringThe CSS class name for the icon element.
optionsArrayAn array of options for 'select', 'checkbox', or 'radio' type inputs.
acceptstringThe file types accepted by the input field.
valueanyThe value of the input field.
errorstringThe error message for the input field.
readOnlybooleanIndicates whether the input field is read-only.
disabledbooleanIndicates whether the input field is disabled.
autoFocusbooleanIndicates whether the input field should be focused on render.
multiplebooleanIndicates whether multiple options can be selected.
patternstringThe pattern for input validation.
autoComplete'on''off'The auto-complete behavior for the input field.
spellCheckbooleanIndicates whether spell checking is enabled.
stepnumberThe step value for numeric input fields.
formTarget'_self''_blank''_parent''_top''framename'The target frame for form submission.
altstringThe alternative text for the input field (used for image inputs).
validation(value: any, formValues: IFormValues, formSchema: IFormSchema[]) => string | undefinedA custom validation function for the input field.
trimbooleanIndicates whether leading and trailing whitespace should be removed from the input value.

useForm()

useForm : It's a hook that takes formSchema as an argument and returns an object with the following properties: |

ValuesDescription
formValuesAn object that contains the values of the input fields.
The key is the name of the input field and the value is the value of the input field.
formErrorsAn object that contains the errors of the input fields.
The key is the name of the input field and the value is the error of the input field.
handleChangeA function that takes an event as an argument and updates the value of the input field.
doValidateA function that takes no arguments and validates the input fields.
It returns a boolean value that indicates if the form is valid or not.
Call this function before submitting the form.
handleResetA function that takes no arguments and resets the form values and errors.
setFormValueIf you want to set the form value from the outside, you can use the setFormValue function.
It takes two arguments. The first argument is the name of the input field,
and the second argument is the value that you want to set.
setFormErrorIf you want to set the form error from the outside, you can use the setFormError function.
It takes two arguments. The first argument is the name of the input field,
and the second argument is the error message that you want to set.
setFormDataLet's say you have a form for updating a user information.
If you want to show the previous information in the form,
you can use the setFormData function to set the form values.
It takes an object as an argument. The key is the name of the input field,
and the value is the value that you want to set.

Basic Usage

import { useForm } from 'formash'

const formSchema = [
  {
    type: 'text',
    name: 'name',
    value: '',
    label: 'Name',
    placeholder: 'Enter your name',
    error: 'Please enter your name',
    required: true,
  },
  // Add more fields as needed
]

const Form = () => {
  const { formValues, formErrors, handleChange, doValidate } = useForm(formSchema)
  const handleSubmit = e => {
    e.preventDefault()
    const isValid = doValidate()
    if (isValid) {
      // Handle form submission logic here
    }
  }
  return (
    <form onSubmit={handleSubmit}>
      {formSchema.map(item => {
        return (
          <div key={item.name}>
            <label htmlFor={item.name}>{item.label}</label>
            <input
              type={item.type}
              name={item.name}
              value={formValues[item.name]}
              onChange={handleChange}
              placeholder={item.placeholder}
            />
            <div> {formErrors[item.name]} </div>
          </div>
        )
      })}
      <button> Submit </button>
    </form>
  )
}

Additional Input Types

How to use with select input

import { useForm } from 'formash'

const formSchema = [
  {
    value: '',
    name: 'menu',
    label: 'Menu',
    type: 'select',
    required: true,
    error: 'Please select your favorite menu',
    placeholder: 'What is your favorite menu?',
    options: [
      {
        label: 'Pizza',
        value: 'pizza',
      },
      {
        label: 'Burger',
        value: 'burger',
      },
    ],
  },
]

const Select = () => {
  const { formValues, formErrors, handleChange } = useForm(formSchema)

  return (
    <div>
      {formSchema.map(item => {
        return (
          <div>
            <select name={item.name} onChange={handleChange} value={formValues[item.name]}>
              <option selected>{item.label}</option>
              {item.options?.map(option => {
                return (
                  <option key={option.name} value={option.value}>
                    {option.label}
                  </option>
                )
              })}
            </select>
            <div> {formErrors[item.name]} </div>
          </div>
        )
      })}
    </div>
  )
}

How to use with input checkbox type

Note: to checked the checkbox, you need to check the option value in formValuesitem.name array

import { useForm } from 'formash'

const formSchema = [
  {
    value: [],
    name: 'hobbies',
    required: false,
    label: 'Hobbies',
    type: 'checkbox',
    error: 'Please select your hobbies',
    placeholder: 'What is your hobbies?',
    options: [
      {
        id: 'football',
        label: 'Football',
        value: 'football',
      },
      {
        id: 'cricket',
        label: 'Cricket',
        value: 'cricket',
      },
    ],
  },
]

const CheckBox = () => {
  const { formValues, formErrors, handleChange } = useForm(formSchema)

  return (
    <div>
      {formSchema.map(item => {
        return (
          <div>
            {item.options?.map(option => {
              return (
                <div key={option.name}>
                  <input
                    id={option.id}
                    type={item.type}
                    name={item.name}
                    value={option.value}
                    onChange={handleChange}
                    checked={formValues[item.name].includes(option.value)}
                  />
                  <label htmlFor={option.id}>{option.label}</label>
                </div>
              )
            })}
            <div> {formErrors[item.name]} </div>
          </div>
        )
      })}
    </div>
  )
}

How to use with input radio type

Note: to checked the radio, you need to compare the option value with formValuesitem.name if they are equal then it will be checked

import { useForm } from 'formash'

const formSchema = [
  {
    value: '',
    type: 'radio',
    name: 'gender',
    label: 'Gender',
    required: false,
    error: 'Please select your gender',
    placeholder: 'What is your gender?',
    options: [
      {
        id: 'male',
        label: 'Male',
        value: 'male',
      },
      {
        id: 'female',
        label: 'Female',
        value: 'female',
      },
    ],
  },
]

const Radio = () => {
  const { formValues, formErrors, handleChange } = useForm(formSchema)

  return (
    <div>
      {formSchema.map(item => {
        return (
          <div>
            {item.options?.map(option => {
              return (
                <div key={option.name}>
                  <input
                    id={option.id}
                    type={item.type}
                    name={item.name}
                    value={option.value}
                    onChange={handleChange}
                    checked={formValues[item.name] === option.value}
                  />
                  <label htmlFor={option.id}>{option.label}</label>
                </div>
              )
            })}
            <div> {formErrors[item.name]} </div>
          </div>
        )
      })}
    </div>
  )
}

How to use with input file type

Note: with file input type, you don't need to set the value attribute. It will be set automatically when you select the file.

import { useForm } from 'formash';

const formSchema = [
  {
    value: '',
    type: 'file',
    name: 'avatar',
    required: true,
    label: 'Avatar',
    accept: 'image/*',
    placeholder: 'Enter your avatar',
    error: 'Please enter your avatar',
  },
];

const InputFile = () => {
  const { formValues, formErrors, handleChange } = useForm(formSchema)

  return (
    <div>
      {formSchema.map(item => {
        return (
          <div key={item.name}>
            <label htmlFor={item.name}>{item.label}</label>
            <input
              type={item.type}
              id={item.name}
              name={item.name}
              accept={item.accept}
              onChange={handleChange}
              placeholder={item.placeholder}
            />
          </div>
          <div> {formErrors[item.name]} </div>
        );
      })}
    </div>
  );
};

Using useReadFile Hook

The useReadFile hook is designed to read file data and provide it as a base64 encoded string. This is particularly useful when you want to display a preview of image files before uploading them.

import { useReadFile } from 'formash'
const FileInput = () => {
  const { file, setFile } = useReadFile()
  return (
    <div>
      <input type="file" onChange={e => setFile(e.target.files[0])} />
      {file && <img src={file} />}
    </div>
  )
}

How to validate the form

The doValidate function is used to validate the form. It returns a boolean value: true if the form is valid and false otherwise. Make sure to call this function to obtain form errors.

import { useForm } from 'formash'

const formSchema = []

const Form = () => {
  const { doValidate } = useForm(formSchema)

  const handleSubmit = () => {
    const isValid = doValidate()
    if (isValid) {
      // do something
    }
  }

  return <form onSubmit={handleSubmit}> </form>
}

How to set the form value from outside

The setFormValue function allows you to set form values programmatically. Provide the name of the input field as the first argument and the desired value as the second argument.

const { setFormValue } = useForm(formSchema)
setFormValue('email', 'someone@gmail.com')

How to set data from the server to the form

The setFormData function is useful when you need to populate the form with data fetched from the server. It takes an object as an argument, where the keys represent input field names, and the values are the corresponding values to be set.

const { setFormData, formValues } = useForm(formSchema)
useEffect(() => {
  const fetchData = async () => {
    const response = await fetch('api/user')
    const data = await response.json()
    // data = { name: 'John', email: 'john@gmail.com' }
    setFormData(data)
  }
  fetchData()
}, [])

How to set the form error from outside

While useForm handles form validation and sets errors automatically, you may manually set form errors with the setFormError function. Provide the input field name as the first argument and the desired error message as the second argument.

const { setFormError } = useForm(formSchema)
setFormError('email', 'Please enter a valid email')

How to reset the form state

The handleReset function resets the form state, clearing both form values and errors.

const { handleReset } = useForm(formSchema)
handleReset()

let's see how to use with typescript

Formash provides TypeScript support with several helpful types:

  • IFormSchema: Used to create and map over your form schema.
  • IFormOption: Used with select, checkbox, and radio options.
  • IFormValues: Represents the form values.
  • IFormErrors: Represents the form errors.
import { useForm, IFormSchema, IFormOption } from 'formash';

const formSchema: IFormSchema[] = [];

const Form = () => {
  const { formValues } = useForm(formSchema);

  return (
    <div>
      {formSchema.map((item: IFormSchema) => {
        return {item.options?.map((option: IFormOption) => {})}
      })}
    </div>
  );
};

Best Practices

  • Split your form elements into separate components and use them in your Form component.
  • Create a schema for your form and pass it to the useForm hook.
  • from useForm hook get the formValues and handleChange function to handle the input change.
  • map over the schema and render the form elements.
  • Use conditional rendering based on the type of form element within the map function.
  • You are done.
import { useForm } from 'formash'

const formSchema = []

const Form = () => {
  const { formValues, formErrors, handleChange } = useForm(formSchema)

  return (
    <form>
      {formSchema.map(item => {
        if (item.type === 'select')
          return (
            <Select
              key={item.name}
              formElement={item}
              handleChange={handleChange}
              formValue={formValues[item.name]}
              formError={formErrors[item.name]}
            />
          )

        if (item.type === 'textarea')
          return (
            <TextArea
              key={item.name}
              formElement={item}
              handleChange={handleChange}
              formValue={formValues[item.name]}
              formError={formErrors[item.name]}
            />
          )

        if (item.type === 'checkbox')
          return (
            <Checkbox
              key={item.name}
              formElement={item}
              handleChange={handleChange}
              formValue={formValues[item.name]}
              formError={formErrors[item.name]}
            />
          )

        if (item.type === 'radio')
          return (
            <Radio
              key={item.name}
              formElement={item}
              handleChange={handleChange}
              formValue={formValues[item.name]}
              formError={formErrors[item.name]}
            />
          )

        if (item.type === 'file')
          return (
            <InputFile
              key={item.name}
              formElement={item}
              handleChange={handleChange}
              formValue={formValues[item.name]}
              formError={formErrors[item.name]}
            />
          )

        if (item.type === 'file')
          return (
            <Input
              key={item.name}
              formElement={item}
              handleChange={handleChange}
              formValue={formValues[item.name]}
              formError={formErrors[item.name]}
            />
          )
      })}
    </form>
  )
}

Authors

2.0.9

9 months ago

2.1.0

9 months ago

2.0.8

2 years ago

2.0.7

2 years ago

2.0.6

2 years ago

2.0.5

2 years ago

2.0.4

2 years ago

2.0.3

2 years ago

2.0.2

2 years ago

2.0.1

2 years ago

2.0.0

2 years ago

1.0.1

2 years ago

1.0.0

2 years ago