In my React code, along with other input types, I also have to use ToggleButtonGroup component of material-ui. This component is not directly supported by formik-material-ui and I've been trying to write a custom wrapper without much success. This is how my component looks(formikToggleButtonGroup.tsx):
import * as React from 'react';
import MuiToggleButtonGroup, {
ToggleButtonGroupProps as MuiToggleButtonGroupProps,
} from '@material-ui/lab/ToggleButtonGroup';
import { FieldProps } from 'formik';
export interface ToggleButtonGroupProps
extends FieldProps,
Omit<MuiToggleButtonGroupProps, 'name' | 'value'> {}
export function fieldToToggleButtonGroup({
field,
// Exclude Form
form,
...props
}: ToggleButtonGroupProps): MuiToggleButtonGroupProps {
return {
...props,
...field,
};
}
export default function ToggleButtonGroup(props: ToggleButtonGroupProps) {
return <MuiToggleButtonGroup {...fieldToToggleButtonGroup(props)} />;
}
ToggleButtonGroup.displayName = 'FormikMaterialUIToggleButtonGroup';`
Then, I'm trying to use it like this:
import Layout from '../../components/layout'
import Header from '../../components/header'
import ToggleButtonGroup from '../../components/formikToggleButtonGroup.tsx'
import React, { useState } from 'react';
import { makeStyles } from '@material-ui/core/styles';
import Button from '@material-ui/core/Button';
import Container from '@material-ui/core/Container';
import CssBaseline from '@material-ui/core/CssBaseline';
import Grid from '@material-ui/core/Grid';
import Box from '@material-ui/core/Box';
import ToggleButton from '@material-ui/lab/ToggleButton';
import { withStyles } from '@material-ui/core/styles';
import { green, orange } from '@material-ui/core/colors';
import Radio from '@material-ui/core/Radio';
import FormControlLabel from '@material-ui/core/FormControlLabel';
import FormControl from '@material-ui/core/FormControl';
import FormLabel from '@material-ui/core/FormLabel';
import * as Yup from "yup";
import { Formik, Form, Field} from 'formik';
import { TextField, RadioGroup } from 'formik-material-ui';
import ToggleButtonGroup from '../../components/formikToggleButtonGroup.tsx'
import ToggleButton from '@material-ui/lab/ToggleButton';
const StyledButton = withStyles((theme)=>({
root: {
background: theme.palette.background.paper,
color: theme.palette.text.primary,
marginBottom: theme.spacing(3),
marginRight: theme.spacing(4),
borderRadius: '0',
borderWidth: '1px',
borderColor: theme.palette.divider,
borderLeft:'1px solid rgba(0, 0, 0, 0.12) !important',
padding: '0 30px',
fontSize:'0.7rem',
fontWeight:'400',
'&$selected': {
color: theme.palette.background.default,
backgroundColor: theme.palette.warning.main,
},
'&:hover': {
color: theme.palette.background.default,
backgroundColor: theme.palette.warning.light,
},
'&$selected:hover': {
color: theme.palette.background.default,
backgroundColor: theme.palette.warning.light,
},
},
selected:{
color: theme.palette.background.default,
backgroundColor: theme.palette.warning.main,
},
hover:{
color: theme.palette.background.default,
backgroundColor: theme.palette.warning.light,
},
label: {
textTransform: 'capitalize',
},
}))(ToggleButton);
export default function GetUserInfo() {
const classes = useStyles();
const [selectedValue, setSelectedValue] = useState('yes');
const handleRadioChange = (event) => {
setSelectedValue(event.target.value);
};
const handleSubmit = (evt) => {
evt.preventDefault();
alert(`Submitting Name ${name} ${phone} ${email}`)
}
const handleChange = (event, newAlignment) => {
alert(newAlignment)
if (newAlignment !== null) {
setGrade(newAlignment);
}
};
return (
<Layout title="My first Next page" meta_desc="Best online coding classes for kids & children">
<CssBaseline />
<Header />
<Container component="main" >
<Grid container spacing={4}>
<Grid item xs={12} sm={8} className={classes.boxStyle}>
<Box mx="auto" p={2}>
<Formik
initialValues={initialValues}
validate={
values => {
const errors = {};
if (!values.parentEmail) {
errors.parentEmail = 'Required';
} else if (
!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values.parentEmail)
) {
errors.parentEmail = 'Invalid email address';
} else if (!values.parentName){
errors.parentName = 'Required';
} else if (!values.countryCode){
errors.countryCode = 'Required';
} else if (!values.phone){
errors.phone = 'Required';
} else if (!values.childName){
errors.childName = 'Required';
} else if (!values.grade){
errors.grade = 'Required';
} else if (!values.computer){
errors.computer = 'Required';
}
return errors;
}
}
onSubmit={(values, { setSubmitting }) => {
setTimeout(() => {
setSubmitting(false);
alert(JSON.stringify(values, null, 2));
}, 500);
}}
>
{({ submitForm, isSubmitting }) => (
<Form className={classes.root} autoComplete="off">
<Box>
<Field
component={TextField}
fullWidth
name="childName"
onChange={e => setChildName(e.target.value)}
required id="standard-required" label="Kid's Name"
helperText="Certificate will be issued with this name"/>
</Box>
<Box mt={3} className={classes.labelFont}>
Kid's Grade?
</Box>
<Box mt={2}>
<ToggleButtonGroup
component={ToggleButtonGroup}
mt={7}
name="grade"
//value={grade}
exclusive="true"
//onChange={handleChange}
aria-label="text alignment"
>
<StyledButton className={classes.buttonMargin}
value="1" aria-label="left aligned">
<label class="btn btn-secondary m-2 rounded">
Grade <br/> <strong>1 - 3</strong>
</label>
</StyledButton>
<StyledButton className={classes.buttonMargin} value="2" aria-label="centered">
<label class="btn btn-secondary m-2 rounded ">
Grade <br/> <strong>4 - 6</strong>
</label>
</StyledButton>
<StyledButton className={classes.buttonMargin} value="3" aria-label="right aligned">
<label class="btn btn-secondary m-2 rounded">
Grade <br/> <strong>7 - 9</strong>
</label>
</StyledButton>
<StyledButton className={classes.buttonMargin} value="4" aria-label="justified">
<label class="btn btn-secondary m-2 rounded">
Grade <br/><strong>10 - 12</strong>
</label>
</StyledButton>
</ToggleButtonGroup>
</Box>
<Button
disabled={isSubmitting}
onClick={submitForm}
//type="submit"
//onClick={handleSubmit}
fullWidth
variant="contained"
color="primary"
className={classes.submit}>Let's Start
</Button>
</Form>
)}
</Formik>
</Box>
</Grid>
</Grid>
</Container>
</Layout>
)
}
The problem I am facing is that value of ToggleButtonGroup is not getting set by Formik. It always shows the initial value.