Form

Example

Code


    import React from "react"
    import Label from "components/ui/Form/Label"
    import Input from "components/ui/Form/Input"

    function reducer(state, action) {
      const updatedValues = state
      const currentErrors = Object.assign({}, updatedValues.errors)
  
      if ('username' in action) {
        updatedValues.username = action.username
        updatedValues.errors.username = isBlankString(updatedValues.username)
      }
      
      if ('firstName' in action) {
        updatedValues.firstName = action.firstName
        updatedValues.errors.firstName = isBlankString(updatedValues.firstName)
      }
  
      if ('lastName' in action) {
        updatedValues.lastName = action.lastName
        updatedValues.errors.lastName = isBlankString(updatedValues.lastName)
      }
  
      const needRendering = (
        currentErrors.username !== updatedValues.errors.username ||
        currentErrors.firstName !== updatedValues.errors.firstName ||
        currentErrors.lastName !== updatedValues.errors.lastName
      )
  
      if (!!action.render || needRendering) { setCurrentState(1 - currentState) }
  
      return updatedValues
    }
  
  
    const [currentState, setCurrentState] = useState(0)
    const [values, dispatch] = useReducer(reducer, { username: '', firstName: '', lastName: '', errors: {}, updated: {} })
  
  
    async function validate() {
      await dispatch({
        username: values.username || '',
        firstName: values.firstName || '',
        lastName: values.lastName || '',
        render: true
      })
    }
  
    async function handleSubmit() {
      await validate()
  
      const isValid = !values.errors.username && ! values.errors.firstName && ! values.errors.lastName
  
      if (!!values && !!isValid) {
        const fields = {
          username: values.username,
          firstName: values.firstName,
          lastName: values.lastName,
        }
        console.log(fields)
      }
    }

    <div className="grid grid-cols-2 gap-4">
      <div className="col-span-2">
        <Label htmlFor="username">Username</Label>
        <Input
          listening={true}
          name="username"
          type="text"
          className="rounded"
          error={values.errors.username}
          onChange={value => dispatch({ username: value })}
        />
      </div>
      <div className="col-span-2">
        <Label htmlFor="firstName">First Name</Label>
        <Input
          listening={true}
          name="firstName"
          type="text"
          className="rounded"
          error={values.errors.firstName}
          onChange={value => dispatch({ firstName: value })}
        />
      </div>
      <div className="col-span-2">
        <Label htmlFor="lastName">Last Name</Label>
        <Input
          listening={true}
          name="lastName"
          type="text"
          className="rounded"
          error={values.errors.lastName}
          onChange={value => dispatch({ lastName: value })}
        />
      </div>
      <div className="col-span-2">
        <button
          className="group relative w-full flex justify-center py-2 px-4 border border-transparent text-md leading-7 font-medium rounded-md text-white bg-primary-600 hover:bg-primary-500 focus:outline-none focus:border-primary-700 focus:ring-primary active:bg-primary-700 transition duration-150 ease-in-out"
          onClick={handleSubmit}
        >
          Save
        </button>
      </div>
    </div>