React Hook Form Register Two Range Inputs

Viewed 837

I'm in the process of putting together a reusable range slider component with two knobs on the slider. Its a slightly modified version of https://codesandbox.io/s/b9l0g?file=/src/multiRangeSlider/MultiRangeSlider.tsx:95-131. To accomplish this i'm using two input fields. Is there a way to register both input fields so they return in an array when the form data is submitted? Something like [24, 100]

View

const {
    register,
    handleSubmit,
    formState: { errors },
} = useForm()

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

return (
    <form onSubmit={handleSubmit(onSubmit)}>
        <RangeSlider
            name="rangeslider"
            register={register}
            errors={errors}
            isRequired={true}
            min={0}
            max={1000}
        />
    </form>
)

RangeSlider

    <input
        type="range"
        {...register(name, {
            required: {
                value: isRequired,
                message: `${name} is required`,
            },
        })}
        min={min}
        max={max}
        value={minVal}
        ref={minValRef}
        onChange={(event: ChangeEvent<HTMLInputElement>) => {
            const value = Math.min(+event.target.value, maxVal - 1)
            setMinVal(value)
            event.target.value = value.toString()
        }}
        className={`thumb thumb--zindex-3 ${
            minVal > max - 100 ? 'thumb--zindex-5' : ''
        }`}
    />
    <input
        type="range"
        {...register(name, {
            required: {
                value: isRequired,
                message: `${name} is required`,
            },
        })}
        min={min}
        max={max}
        value={maxVal}
        ref={maxValRef}
        onChange={(event: ChangeEvent<HTMLInputElement>) => {
            const value = Math.max(+event.target.value, minVal + 1)
            setMaxVal(value)
            event.target.value = value.toString()
        }}
        className="thumb thumb--zindex-4"
    />

    <div className="slider">
        <div className="slider__track"></div>
        <div ref={range} className="slider__range"></div>
        <div className="slider__left-value">{minVal}</div>
        <div className="slider__right-value">{maxVal}</div>
    </div>
1 Answers

You cannot register two inputs with the same name and retrieve values for both. However, you can alter their names. For example:

{...register(`${name}.lower`)}

and

{...register(`${name}.upper`)}

Let's say name = "age", then your data object will look like this:

{
    age: {
         lower: 12,
         upper: 18
    }        
}

However, it might be easier in the first place to use a Controller. I have edited the code sandbox you used as a template to show how a Controller can be used here.
Look here.

Related