Reputation: 3
I'm trying to validate a react-select input field with react-hook-form.(Required input) But I can't seem to do this with the code block below. Can anyone point me in the right direction?
<Controller
as={Select}
options={statusOptions}
name="status"
control={control}
className="infoItemDropdown"
rules={{ required: true }}
styles={customStyles}
/>
Upvotes: 0
Views: 4342
Reputation: 1
You can also use setError and check by clicking on Submit
// ... your code
const {
control,
handleSubmit,
setError,
formState: { isValid, errors },
} = useForm<FormValues>({
mode: 'all'
})
const onSubmit = (data: FormValues) => {
if (!data.youSelectName?.value) {
setError('youSelectName', { message: 'This field is required.' })
return
}
// ... your code
}
return (
// ... your code
<form onSubmit={handleSubmit(onSubmit)}>
<Controller
name='youSelectName'
control={control}
render={({ field: { onChange, value } }) => (
<Select
onChange={onChange}
options={options}
value={value}
/>
)}
/>
{errors.youSelectName && (<div>{errors.youSelectName.message}</div>)}
<button
type='submit'
disabled={!isValid}
>
submit
</button>
</form>
// ... your code
)
Upvotes: 0
Reputation: 1
You can use these rules to make it required:
rules={{
validate: (value) => {
if (typeof value === 'object' && Object.keys(value).length === 0) {
return 'This field is required.';
}
return true;
},
}}
react-select returns an empty object if no option is selected, so you just need to check for that empty object and return the message.
Upvotes: 0
Reputation: 266
You can wrapper the component react-select:
import Select from 'react-select';
import React, { useState } from 'react';
import PropTypes from 'prop-types';
const RenderSelect = (props) => {
const {
field: {
value,
onChange,
},
data,
} = props;
const [selectedOption, setSelectedOption] = useState();
const handleChange = (e) => {
onChange(e.value);
setSelectedOption(e);
};
return (
<Select
value={selectedOption}
onChange={handleChange}
options={data}
/>
);
};
RenderSelect.propTypes = {
data: PropTypes.arrayOf(
PropTypes.shape({
value: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
]).isRequired,
label: PropTypes.string.isRequired,
}),
).isRequired,
field: PropTypes.shape({
value: PropTypes.oneOfType([
PropTypes.string.isRequired,
PropTypes.number.isRequired,
]),
onChange: PropTypes.func.isRequired,
}),
};
RenderSelect.defaultProps = {
field: { onChange: () => {}, value: '' },
};
export default RenderSelect;
And use it in react hook form:
export default function MyForm() {
const {
handleSubmit,
formState: { isValid },
control,
} = useForm({ mode: 'onChange' });
const onSubmit = (values) =>{
console.log(values)
};
const data = [
{ value: 'chocolate', label: 'Chocolate' },
{ value: 'strawberry', label: 'Strawberry' },
{ value: 'vanilla', label: 'Vanilla' },
];
return (
<form onSubmit={handleSubmit(onSubmit)}>
<Controller
name="select_something"
control={control}
rules={{ required: true }}
render={({ field }) => (<RenderSelect field={field} data={data}/>)
}
/>
<button
disabled={!isValid}
type="submit"
>
Save
</button>
</form>
);
}
This way disable the button submit if the select not has a value.
Upvotes: 1