I'm using formik react library and trying to update 2 fields, based on the onChange event of another. For example,
price = quantity * totalPrice
price :
onChange={() => {setFieldValue('quantity',values.quantity? values.price / values.totalPrice:values.quantity, );
setFieldValue('totalPrice',values.totalPrice? values.price * values.quantity: values.totalPrice,);}}
quantity :
onChange={(value, e) => { this.disableFiled(value, e); setFieldValue('totalPrice',values.price ? values.price * values.totalPrice : ' ',);}}
totalPrice:
onChange={(value, e) => { this.disableFiled(value, e);setFieldValue('quantity',values.price ? values.totalPrice / price : ' ', ); }}
when quantity has value, total price will be disabled and vice versa.but it doesn't calculate other fields correctly
You don't need to use value={values.name} you can use Formik props like onSubmit to get your values. Also what version are you using? please note that render method has been deprecated.
FieldByName(name = 'salary_fld'); ret_value = fld. SetFieldValue(value = 10000.0); The FieldByName method returns the field object that represents the given field (salary_fld, in this example), and the SetFieldValue methods uses that field object to set the value of the field.
Returns true if values are not deeply equal from initial values, false otherwise. dirty is a readonly computed property and should not be mutated directly.
This is how I do this.
import React from "react";
import "./styles.css";
import { Formik } from "formik";
import * as Yup from "yup";
import CalculatedField from "./CalculatedField";
const App = () => (
<div className="app">
<Formik
initialValues={{ price: "", quantity: "", totalPrice: "" }}
onSubmit={async values => {
await new Promise(resolve => setTimeout(resolve, 500));
alert(JSON.stringify(values, null, 2));
}}
validationSchema={Yup.object().shape({
price: Yup.number("It's a number").required("Required"),
quantity: Yup.number("It's a number").required("Required"),
totalPrice: Yup.number("It's a number").required("Required")
})}
>
{props => {
const {
values,
touched,
errors,
isSubmitting,
handleChange,
handleBlur,
handleSubmit,
setFieldValue
} = props;
return (
<form onSubmit={handleSubmit}>
<div className="input-row">
<label htmlFor="quantity" style={{ display: "block" }}>
Quantity
</label>
<input
id="quantity"
name="quantity"
placeholder="Enter quantity"
type="number"
value={values.quantity}
onChange={handleChange}
onBlur={handleBlur}
className={
errors.quantity && touched.quantity
? "text-input error"
: "text-input"
}
/>
{errors.quantity && touched.quantity && (
<div className="input-feedback">{errors.quantity}</div>
)}
</div>
<div className="input-row">
<label htmlFor="price" style={{ display: "block" }}>
Price
</label>
<input
id="price"
name="price"
placeholder="Enter your price"
type="number"
value={values.price}
onChange={handleChange}
onBlur={handleBlur}
className={
errors.price && touched.price
? "text-input error"
: "text-input"
}
/>
{errors.price && touched.price && (
<div className="input-feedback">{errors.price}</div>
)}
</div>
<div className="input-row">
<label htmlFor="totalPrice" style={{ display: "block" }}>
Total Price
</label>
<CalculatedField
id="totalPrice"
type="number"
name="totalPrice"
value={values.totalPrice}
values={values}
setFieldValue={setFieldValue}
onChange={handleChange}
onBlur={handleBlur}
className={
errors.totalPrice && touched.totalPrice
? "text-input error"
: "text-input"
}
/>
{errors.totalPrice && touched.totalPrice && (
<div className="input-feedback">{errors.totalPrice}</div>
)}
</div>
<div className="input-row">
<button type="submit" disabled={isSubmitting}>
Submit
</button>
</div>
</form>
);
}}
</Formik>
</div>
);
export default App;
import React, { useEffect } from "react";
const CalculatedField = props => {
useEffect(() => {
var val = 0;
if (props.values.price && props.values.quantity) {
val = props.values.price * props.values.quantity;
}
props.setFieldValue("totalPrice", val);
}, [props.values]);
return (
<input
id="totalPrice"
type="number"
name="totalPrice"
value={props.values.totalPrice}
/>
);
};
export default CalculatedField;
This is basically achieved by calling setFieldValue method within useEffect hooks in the CalculatedField component. Please remember useEffect will watch for the change of the values and run the setFieldValue method when they are modified.
Please follow the CodeSandbox demo. https://codesandbox.io/s/affectionate-mirzakhani-who30?file=/src/App.js
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With