I have a react-hook-form form and yup validation. What I'm trying to do is to format an input with react-number-format but also to pass float value to validation and to submit.
Here's the codesandbox: https://codesandbox.io/s/keen-field-26ub7
In InvoiceData.js there is an input that react-number-format is using. I would like to validate this input against the value above that (grossValue) but I think I cannot do this without parsing the value to float back again.
First solution
Create a NumberFormat
class inside of InvoiceData
and use the same formatting props, to retrieves its removeFormatting
function
InvoiceData.js
const getProperties = ({ invoice, register, errors }) => ({
customInput: TextField,
inputRef: register,
variant: "outlined",
name: "amountToPay",
label: "InvoiceData.amountToPay",
helperText: ((errors || {}).amountToPay || {}).message,
error: (errors || {}).amountToPay,
thousandSeparator: " ",
suffix: " PLN",
defaultValue: (invoice || {}).amountToPay,
decimalScale: 2,
fixedDecimalScale: true
});
export const removeFormatting = (value, props = {}) => {
const properties = getProperties(props);
let res = Number.parseFloat(
new NumberFormat(properties).removeFormatting(value)
);
if (properties.decimalScale) {
return res * Math.pow(10, -properties.decimalScale);
}
return res;
};
You can then use that function to check if your submitted form is valid:
Form.js
const onSubmit = async (data) => {
if (removeFormatting(data.amountToPay) === responseData.amountGross) {
// action when valid
console.log("valid");
} else {
// action when invalid
}
};
see your modified code using this link: https://codesandbox.io/s/heuristic-paper-4ycuh
Second solution
Use a state to remember the amountToPay
such as follow:
const [amountToPay, setAmountToPay] = useState(responseData.amountToPay)
Add a callback function to your InvoiceData
component and use onValueChange
from NumberFormat
to call that function, eg :
const InvoiceData = ({...props, handleChanged} => {
return (
<NumberFormat
// whatever props you need
onValueChange={(value) => handleChanged(value.floatValue)}
/>
);
}
You can then pass on the setAmountToPay
that we defined previously, and pass it to InvoiceData
in that manner:
<InvoiceData
// whatever props you need
handleChanged={setAmountToPay}
/>
You can then validate your submit as follow
const onSubmit = async () => {
if (amountToPay === responseData.amountGross) {
// action when valid
console.log("valid");
} else {
// action when invalid
}
};
I think I've found an answer building on top of what Alexandre ELIOT did in the second solution. Instead of passing amountToPay to onSubmit function I've passed it to the NumberFormat itself.
<NumberFormat
customInput={TextField}
inputRef={register}
variant="outlined"
name="amountToPay"
label={t('InvoiceData.amountToPay')}
helperText={
/* eslint-disable-next-line */
amountToPay> invoice.amountGross
? 'cannot be greater that amount gross'
: amountToPay=== 0
? 'cannot be 0'
: null
}
error={amountToPay> invoice.amountGross || amountToPay=== 0}
thousandSeparator={' '}
suffix=" PLN"
defaultValue={invoice.amountToPay}
onValueChange={(value) => handleValueChange(value.floatValue)}
decimalScale={2}
fixedDecimalScale
/>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.