Reputation: 629
Why the function onSubmit does not get triggered in my code? (I need to keep it all as it is, or ar least to function in the same manner, the Input tag I have managed by Controller, needs to show a state "price" all the time, which is changed by two functions (handlePriceInputChange, handleSelectedBox)
const schema = yup
.object({
voucherPrice: yup.number().positive().required(),
})
.required();
function PriceSelection(props) {
const {
register,
handleSubmit,
control,
formState: { errors },
} = useForm({
resolver: yupResolver(schema),
});
const onSubmit = (data) => {
console.log("does not work?", data);
};
const classes = useStylesPriceSelection();
const [selected, setSelected] = useState(false);
const [price, setPrice] = useState("");
const handleSelectedBox = (ev) => {
console.log("", price);
setSelected(ev.target.getAttribute("data-boxprice"));
setPrice(parseInt(ev.target.getAttribute("data-price")));
};
const handlePriceInputChange = (ev) => {
console.log("change", price);
setPrice(parseInt(ev.target.value));
};
const priceBox1 = 25;
const priceBox2 = 50;
const priceBox3 = 75;
const priceBox4 = 100;
return (
<div>
<section className={classes.priceBoxWrap}>
<div
data-boxprice="1"
data-price={`${priceBox1}`}
onClick={(ev) => handleSelectedBox(ev)}
className={clsx(
classes.priceBox,
((selected === "1" && price === priceBox1) ||
price === priceBox1) &&
classes.priceBoxSelected
)}
>
{`${priceBox1}€`}
</div>
<div
data-boxprice="2"
data-price={`${priceBox2}`}
onClick={(ev) => handleSelectedBox(ev)}
className={clsx(
classes.priceBox,
((selected === "2" && price === priceBox2) ||
price === priceBox2) &&
classes.priceBoxSelected
)}
>
{`${priceBox2}€`}
</div>
</section>
<section className={classes.priceBoxWrap}>
<div
data-boxprice="3"
data-price={`${priceBox3}`}
onClick={(ev) => handleSelectedBox(ev)}
className={clsx(
classes.priceBox,
((selected === "3" && price === priceBox3) ||
price === priceBox3) &&
classes.priceBoxSelected
)}
>
{`${priceBox3}€`}
</div>
<div
data-boxprice="4"
data-price={`${priceBox4}`}
onClick={(ev) => handleSelectedBox(ev)}
className={clsx(
classes.priceBox,
((selected === "4" && price === priceBox4) ||
price === priceBox4) &&
classes.priceBoxSelected
)}
>
{`${priceBox4}€`}
</div>
</section>
<form onSubmit={handleSubmit(onSubmit)}>
<Controller
name="voucherPrice"
control={control}
defaultValue={false}
rules={{ required: true }}
render={({ field: { onChange, value, ref, ...field } }) => (
<Input {...field} onChange={(ev) => handlePriceInputChange(ev)} value={price} type="number" innerRef={ref} />
)}
/>
<p>{errors.voucherPrice?.message}</p>
<Button
variant="contained"
sx={{ mt: 1, mr: 1 }}
type="submit"
>
{"Continue"}
</Button>
</form>
</div>
);
}
export default PriceSelection;
Upvotes: 0
Views: 2089
Reputation: 6949
You can just use react-hook-form
for this situation and can get rid of the additional local state management via useState
. I reworked your example and removed the data
attributes and just passed the price values for each box via the onClick
callback.
const schema = yup
.object({
voucherPrice: yup.number().positive().required()
})
.required();
const priceBox1 = 25;
const priceBox2 = 50;
const priceBox3 = 75;
const priceBox4 = 100;
const selectedStyles = { outline: "2px solid green" };
function PriceSelection(props) {
const {
handleSubmit,
control,
formState: { errors },
setValue,
watch
} = useForm({ resolver: yupResolver(schema) });
const voucherPrice = watch("voucherPrice");
const onSubmit = (data) => {
console.log(data);
};
const setVoucherPrice = (price) => () => setValue("voucherPrice", price);
return (
<div>
<section>
<div
className="pricebox"
style={voucherPrice === priceBox1 ? selectedStyles : null}
onClick={setVoucherPrice(priceBox1)}
>
{`${priceBox1}€`}
</div>
<div
className="pricebox"
style={voucherPrice === priceBox2 ? selectedStyles : null}
onClick={setVoucherPrice(priceBox2)}
>
{`${priceBox2}€`}
</div>
</section>
<section>
<div
className="pricebox"
style={voucherPrice === priceBox3 ? selectedStyles : null}
onClick={setVoucherPrice(priceBox3)}
>
{`${priceBox3}€`}
</div>
<div
className="pricebox"
style={voucherPrice === priceBox4 ? selectedStyles : null}
onClick={setVoucherPrice(priceBox4)}
>
{`${priceBox4}€`}
</div>
</section>
<form onSubmit={handleSubmit(onSubmit)}>
<Controller
name="voucherPrice"
control={control}
rules={{ required: true }}
defaultValue={0}
render={({ field: { ref, ...field } }) => (
<Input {...field} type="number" innerRef={ref} />
)}
/>
<p>{errors.voucherPrice?.message}</p>
<Button variant="contained" sx={{ mt: 1, mr: 1 }} type="submit">
{"Continue"}
</Button>
</form>
</div>
);
}
Upvotes: 1
Reputation: 555
If the handleSubmit function does not call e.preventDefault your page will refresh, to fix this you can wrap the handler like this:
...
const _handleSubmit = (e) => {
e.preventDefault()
handleSubmit(e)
}
...
<form onSubmit={_handleSubmit}>
...
Upvotes: 1