Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How React-hook-form interacting with each another fields?

So I am basically new with-react-hook-form I have created a form with controlled inputs, where my conditions for 2nd input is based on my first input. My 1st input is duration where I have 2 options 'Monthly' and 'Yearly'. My 2nd input is Budget where the minimum budget is 200 for Monthly and 400 for Yearly.

This is my code:

<div style={{ marginTop: theme.spacing(1) }}>
    <Controller
      as={Select}
      row
      name="duration"
      control={control}
      defaultValue="Monthly"
      fullWidth
      label={<FormattedMessage {...messages.duration} />}
      margin="normal"
      options={DURATION_OPTIONS}
      rules={{
        required: 'Required'
      }}
    />
  </div>


  <div>
    <Controller
      as={NumberField}
      row
      name="budget"
      control={control}
      defaultValue="1000"
      fullWidth
      label={<FormattedMessage {...messages.howMuchBudget} />}
      margin="normal"
      rules={{
        required: true,
        min: {
          value: 400,
          message: 'Min is 400',
        }
      }}
    />
  </div>

Now I want to trigger my 2nd field validation based on my 1st field validation dynamically. if my duration is Monthly selected then the min validation for 2nd input should be 200 and if my duration is selected as Yearly then min validation for 2nd input should be 400.

Any help will be highly appreciated.

like image 968
Pitty Avatar asked Apr 07 '26 08:04

Pitty


2 Answers

Here's a basic example. In this case, the last name has to be shorter than the first name, otherwise you'll get an error.

function App() {
  const { register, handleSubmit, errors, getValues } = useForm({mode:'onChange'});

  const onSubmit = (data) => {
    console.log(data);
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <label>First name</label>
      <input name="firstName" defaultValue='Potato' ref={register} />

      <label>Last name (must be shorter than first name)</label>
      <input name="lastName" ref={register({
        validate: {
          shorterThanFirstName: value => value.length < getValues().firstName?.length,
        }
      })} />
      {errors.lastName && <p>Last name must be shorter than first name</p>}

      <input type="submit" />
    </form>
  );
}
like image 90
Jayce444 Avatar answered Apr 09 '26 19:04

Jayce444


2024 Example using yup validation:

import { useForm } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";
import * as yup from "yup";

const MY_SENSORED_CONST = "4";

const schema = yup
.object({
    fieldStringArray: yup.string().nullable(),
    fieldDependsOnAnother: yup
    .string()
    .when("fieldStringArray", (fieldAreaOfUse, schema) => {
        const currStrArr = fieldAreaOfUse[0]; // probably only array when using radiobuttons
        if (currStrArr.split(",").includes(MY_SENSORED_CONST)) {
            return schema.required();
        }
        return schema.nullable();
    }),
})
.required();

export function Component(props: any /*not any but u dont need to know*/) {

    const {
        register,
        handleSubmit,
        formState: { errors },
    } = useForm({
        resolver: yupResolver(schema),
        mode: "onChange",
        reValidateMode: "onChange",
    });
    const onSubmit = (/* data */) => props.next(); // this is only called when all fields were valid
    
    return (
        <form onSubmit={handleSubmit(onSubmit)}>
            <input
                {...register("fieldStringArray")}
            />
            <input
                {...register("fieldDependsOnAnother")}
            />

            <button type="submit">Send it</button>
        </form>
    );
}
like image 34
OZZIE Avatar answered Apr 09 '26 18:04

OZZIE



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!