I am working on a react project and have built a form framework which wraps material ui, around the redux form.
** sandbox https://codesandbox.io/s/condescending-banzai-re6l3
I am unsure how fix a bug - where if the grouped checkbox field is set as validate - to only have a required message appear under the group of checkboxes - then demand all checkboxes to be required.
Here is the current code base
//renderGroupedCheckboxes
import React from "react";
import { Field } from "redux-form";
import FormControl from "@material-ui/core/FormControl";
import FormLabel from "@material-ui/core/FormLabel";
import FormGroup from "@material-ui/core/FormGroup";
//import FormHelperText from '@material-ui/core/FormHelperText';
import renderCheckboxField from "./renderCheckboxField";
const renderGroupedCheckboxes = (fields) => (
<FormControl component="fieldset" fullWidth={true}>
<FormLabel component="legend">{fields.label}</FormLabel>
<FormGroup row>
{fields.names.map((item, j) => {
return (
<Field
key={j}
name={item}
component={renderCheckboxField}
label={fields.options[j].label}
onChange={function (e, newVal) {
fields.onHandle(e.target.name, newVal);
}}
/>
);
})}
</FormGroup>
</FormControl>
);
export default renderGroupedCheckboxes;
the individual checkbox
//renderCheckboxField
import React from "react";
import Checkbox from "@material-ui/core/Checkbox";
import FormControl from "@material-ui/core/FormControl";
import FormControlLabel from "@material-ui/core/FormControlLabel";
import FormHelperText from "@material-ui/core/FormHelperText";
const renderCheckboxField = ({
input,
rows,
multiline,
label,
meta: { touched, error, warning }
}) => (
<FormControl component="fieldset">
<FormControlLabel
label={label}
control={<Checkbox />}
checked={input.value ? true : false}
{...input}
/>
<FormHelperText error={error && error.length > 0 ? true : false}>
{(error && error.length > 0 ? error : null) ||
(warning && warning.length > 0 ? warning : null)}
</FormHelperText>
</FormControl>
);
export default renderCheckboxField;
Modify renderGroupedCheckboxes.js. We are checking if any of the checkbox is touched and all the checkboxes are having error, then render the error text
import React from "react";
import { Field } from "redux-form";
import FormControl from "@material-ui/core/FormControl";
import FormLabel from "@material-ui/core/FormLabel";
import FormGroup from "@material-ui/core/FormGroup";
import FormHelperText from "@material-ui/core/FormHelperText";
import renderGroupedCheckboxField from "./renderGroupedCheckboxField";
const renderGroupedCheckboxes = (fields) => {
let error = null;
let isAnyFieldTouched = false;
let isAllFieldsError = true;
for (let name of fields.names) {
//if touched is true for any one field, isAnyFieldTouched will
//be true
isAnyFieldTouched = isAnyFieldTouched || fields[name].meta.touched;
if (
error === null &&
fields[name].meta.error &&
fields[name].meta.error.length > 0
) {
error = fields[name].meta.error;
}
//if invalid is false for any one field, isAllFieldsError will
//be false
isAllFieldsError = isAllFieldsError && fields[name].meta.invalid;
}
return (
<FormControl component="fieldset" fullWidth={true}>
<FormLabel component="legend">{fields.label}</FormLabel>
<FormGroup row>
{fields.names.map((item, j) => {
return (
<Field
key={j}
name={item}
component={renderGroupedCheckboxField}
label={fields.options[j].label}
onChange={function (e, newVal) {
fields.onHandle(e.target.name, newVal);
}}
/>
);
})}
</FormGroup>
<FormHelperText error={error && error.length > 0 ? true : false}>
{isAnyFieldTouched && isAllFieldsError && error && error.length > 0
? error
: null}
</FormHelperText>
</FormControl>
);
};
export default renderGroupedCheckboxes;
Create renderGroupedCheckboxField.js as below. The reason we are creating new file it to not impact current behavior of checkbox field.
import React from "react";
import Checkbox from "@material-ui/core/Checkbox";
import FormControl from "@material-ui/core/FormControl";
import FormControlLabel from "@material-ui/core/FormControlLabel";
const renderGroupedCheckboxField = ({
input,
rows,
multiline,
label,
meta: { touched, error, warning }
}) => (
<FormControl component="fieldset">
<FormControlLabel
label={label}
control={<Checkbox />}
checked={input.value ? true : false}
{...input}
/>
</FormControl>
);
export default renderGroupedCheckboxField;
sandbox - https://codesandbox.io/s/funny-fast-f3i12?file=/src/_SharedFormComponents/renderGroupedCheckboxes.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