I am creating wrapped versions of the React-Final-Form field component, essentially creating shareable types of fields to speed development at my company. As a part of that, I wanted to create a group of checkboxes, requiring at least one to be checked - but when I attempt to write the validate function, I only seem to have access to the current field.
When I passed my function to a given field, I get the following:
const mustPickAtLeastOne = (value, allValues, fieldState) => {
console.log(value) //output: false
console.log(allValues) //output: undefined
console.log(fieldState) //output: undefined
}
const mustPickAtLeastOne = () => {
const numberChecked = document.querySelectorAll("." + markerclass + " input[type=\"checkbox\"]:checked").length;
return (numberChecked === 0 ? atLeastOneRequiredMsg : undefined);
}
This option is functional from a browser perspective, but smells pretty bad (both because I am attempting to interact with the underlying DOM nodes directly, and because I then can't test this via Jest/Enzyme - so I am missing unit test coverage to know if I break this in the future).
I am using React-Final-Form 6.3.0/Final-Form 4.16.1 - is there something wrong elsewhere, or why can't I get allValues in my validate function? Or is there an entirely better way to implement my "require at least one of these" validation?
Unfortunately, I had been starting off with the example at https://codesandbox.io/s/k10xq99zmr (making use of the composeValidators function) - as I wanted to allow consumers of my component to provide custom validation functions, as well as have the component itself have one or more built-in validations (and then take the combination of all of the above to pass to the underling field validate property)...which meant that the answer was staring me right in the face:
//...
const composeValidators = (...validators) => value =>
validators.reduce((error, validator) => error || validator(value), undefined);
///...
I corrected it to use the following:
//...
const composeValidators = (...validators) => (value, allValues, fieldState) =>
validators.reduce((error, validator) => error || validator(value, allValues, fieldState), undefined);
///...
Meaning that despite the underlying Final-Form implementation providing all three arguments to each assigned validator function, my use of the composeValidators sample was passing the current field value along...while throwing out/ignoring the other two.
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