Material ui Checkbox is not working in React-hook form - yup

I want to make a Form with validation for that I used react-hook-form with Material UI. And for validation, yup and hook/resolver are also used. when I click the Checkbox I want to show another textField but the checkbox is not working. watch is used for that which comes from react-hook-form(useForm). what is my mistake? plz, help.
Here is my code: - codesanbox

You've to use the Controller or useController for the MUI checkbox, for instance:
<Controller
name="hasPhone"
control={control}
render={({ field }) => (
<FormControlLabel
control={
<Checkbox
defaultValue={data.hasPhone}
defaultChecked={data.hasPhone}
color="primary"
onChange={(e) => field.onChange(e.target.checked)}
checked={field.value}
/>
}
label="Do you have a phone"
/>
)}
/>
👉🏻 https://codesandbox.io/s/practical-morning-v6yp1

for those who are struggling with MUI5, NextJs 12 and RHF 7 in typescript, here is how I make it working
Please note that the RHF Controller is inside the FormControlLabel and not the opposite. Also the defaultValue matters
import { FormControlLabel } from "#mui/material";
import Checkbox, { CheckboxProps } from "#mui/material/Checkbox";
import { Control, Controller } from "react-hook-form";
type ICheckBoxFieldProps = CheckboxProps & {
name: string;
control: Control;
label: string;
};
const CheckBoxField: React.FC<ICheckBoxFieldProps> = ({
name,
control,
label,
defaultChecked,
...rest
}: ICheckBoxFieldProps): JSX.Element => {
return (
<FormControlLabel
label={label}
control={
<Controller
name={name}
control={control}
defaultValue={!!defaultChecked}
render={({ field }) => (
<Checkbox
checked={field.value}
onChange={field.onChange}
{...rest}
/>
)}
/>
}
/>
);
};
export default CheckBoxField;
and how to call it inside a form or a FormProvider
<CheckBoxField
name="istrue"
control={control}
defaultChecked={true}
label="isTrue"
color="success"
/>

Related

mui Select/chip with Reach-hook-form - Can't get the update value (Reactjs)

I've succesfully implemented two seperate reusable MUI TextField and Select components , but having issue with third one, which contains both Mui Select/Chip in one single component, the code is two parts, one is the main component which call the second one,
/// Main component///
const { handleSubmit, reset, formState: { errors }, control } = useForm({
defaultValues: {
contractCode: 'sss', stores: [],
},
resolver: yupResolver(schema)
});
return (
.......
<Box m="1rem 0.7rem"
<FormInputText errors={errors} control={control} name='contractCode' label='Contract Code' />
<FormMultipleSelectChip errors={errors} control={control} name='stores' required label='Stores' />
</Box>
.......
);
/// Below is my Child component to re-use
const names = [
'Oliver Hansen',
'Virginia Andrews',
'Kelly Snyder',
];
export default function MultipleSelectChip({ label, inputProps, control, name, errors,stores }) {
const [personName, setPersonName] = React.useState([]);
const handleChange = (event) => {
const {
target: { value },
} = event;
setPersonName(
};
return (
<div>
<FormControl >
<Typography> Locations </Typography>
<Controller
name={name}
control={control}
render={({ field : { onChange, value, ...rest} }) => (
<Select
{...rest}
multiple
value={personName}
onChange={handleChange}
renderValue={(selected) => (
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 0.5 }}>
{selected.map((value) => (
<Chip key={value} label={value} />
))}
</Box>
)}
MenuProps={MenuProps}
>
{names.map((name) => (
<MenuItem key={name} value={name} >
{name}
</MenuItem>
))}
</Select>
)}
/>
</FormControl>
</div>
);
}
Once I submitted the the form, Im not getting the value for 'stores' as attached, but im getting proper value for rest of the fields, enter image description hereenter image description here
Appreciate if anyone help me to fix this issue
Thanks
Syed

React-hook-form Uncontrolled error when using input mask with material UI textfield

when I'm using a controller with input mask and a text field of the material I can't access the errors at the time of submit.
I already tried to put a default value that they suggested in some similar questions but it didn't work.
Below I left some examples.
Follow the code and image below.
import { TextField } from "#mui/material";
import { Controller } from "react-hook-form";
import InputMask from "react-input-mask";
const InputCustom = ({
control,
errorFieldMessage,
name,
mask,
label,
}: any) => {
return (
<Controller
name={name}
control={control}
defaultValue=""
render={({ field: { onChange, value } }) => (
<InputMask mask={mask} value={value} onChange={onChange}>
{(inputProps: any) => (
<TextField
error={!!errorFieldMessage}
helperText={errorFieldMessage}
label={label}
variant="outlined"
type="text"
fullWidth
required
{...inputProps}
/>
)}
</InputMask>
)}
/>
);
};
when I leave it without the mask and submit, it works.
Follow the code and image below.
import { TextField } from "#mui/material";
import { Controller } from "react-hook-form";
import InputMask from "react-input-mask";
const InputCustom = ({
control,
errorFieldMessage,
name,
mask,
label,
}: any) => {
return (
<Controller
name={name}
control={control}
defaultValue=""
render={({ field: { onChange, value } }) => (
<TextField
error={errorFieldMessage}
label={label}
variant="outlined"
type="text"
fullWidth
required
onChange={onChange}
value={value}
/>
)}
/>
);
};

Material UI - How Do I Pass In Styles Through the Select Component To Change The Popover Menu Look?

I am currently using the following to generate a select dropdown on my page:
<Select>
{options.map((option) => (
<MenuItem
className={classes.selectOption}
key={option}
value={option}
>
<ListItemText primary={option} />
</MenuItem>
))}
</Select>
When I click on the dropdown on the page, an element with MuiPaper-root class appears on the page. This shows me the list of options in menu item format. I would like to style the MuiPaper-root element.
Is there a way to do this by passing in an attribute to the <Select> component?
Yes, you can change the paper by MenuProps
https://material-ui.com/api/select/#props
const useStyles = makeStyles((theme) => ({
paper: {
"& ul": {
backgroundColor: "red",
},
}
}));
export default function CustomizedSelects() {
const classes = useStyles();
return (
<Select MenuProps={{ classes: { paper: classes.paper} }}>
{options.map((option) => (
<MenuItem
className={classes.selectOption}
key={option}
value={option}
>
<ListItemText primary={option} />
</MenuItem>
))}
</Select>);
}

react-semantic-ui-datepickers no form value in redux-form

This issue applied the standard implementation without additional customisations.
The is no value on submit of the form and onChange does not fire with the current value.
<Form onSubmit={handleSubmit(this.onSubmit)}>
<Form.Group>
<Field
component={SemanticDatepicker}
name="working"
dateFormat="DD/MM/YYYY"
label="Date of birth"
placeholder="select your DOB"
size="small"
onChange={(e, value) => {
console.log(e, value);
}}
/>
</Form.Group>
<Form.Field
control={Button}
color="purple"
className="submit-btn"
type="submit"
width={6}
>
Save
</Form.Field>
</Form>
A minimal version can be found here https://github.com/chrishj59/datepickerIssue
I could capture the onChange value by creating a custom component which wrapped the <SemanticDatepicker />. I also added mapStateToProps to log the redux-form values. You can consider this as a starting point and work on this.
//SongList.js
state = {
date: "",
};
render(){
const DatePick = () => {
return (
<SemanticDatepicker
onChange={this.datePickerOnChange}
format="YYYY-MM-DD"
/>
);
};
return (
<Form onSubmit={handleSubmit(this.onSubmit)}>
<Form.Group>
<Field
component={DatePick}
name="working"
dateFormat="DD/MM/YYYY"
label="Date of birth"
placeholder="select your DOB"
size="small"
/>
</Form.Group>
<Form.Field
control={Button}
color="purple"
className="submit-btn"
type="submit"
width={6}
>
Save
</Form.Field>
</Form>
);
}
//App.js
import { connect } from "react-redux";
const App = (props) => {
console.log(props.form);
return (
<div>
{" "}
<SongList />
</div>
);
};
const mapStateToProps = (state) => ({
form: state.form,
});
export default connect(mapStateToProps)(App);
I managed to resolve using semantic-ui-redux-form-fields to wrap the Semantic UI component. This now gives the correct format and value appearing in the validate function and formProps.
import React from "react";
imp ort { fieldEnhance } from "semantic-ui-redux-form-fields";
import { compose } from "redux";
import SemanticDatepicker from "react-semantic-ui-datepickers";
import "react-semantic-ui-datepickers/dist/react-semantic-ui-datepickers.css";
const DatePickerPure = (props) => {
const { currentValue, input, ...rest } = props;
const defaultProps = {
format: "DD/MMM/YYYY",
onChange: (event, data) => input.onChange(data.value),
value: currentValue,
...rest,
};
return <SemanticDatepicker {...props} {...defaultProps} />;
};
export default compose(fieldEnhance)(DatePickerPure);

how to use material-ui Dialog PaperProps

I'm using v1.1.0 of material-ui in React 16.3.2. I'm trying to create a landing page similar to Showcase - Local Insights
where the dialog has opacity (Find foreclosures). I'm trying to use PaperProps for Dialog component described here Dialog doc
Here's a component I've created to try to do this.
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '#material-ui/core/styles';
import Button from '#material-ui/core/Button';
import Dialog from '#material-ui/core/Dialog';
import DialogActions from '#material-ui/core/DialogActions';
import DialogContent from '#material-ui/core/DialogContent';
import DialogTitle from '#material-ui/core/DialogTitle';
import ForwardIcon from '#material-ui/icons/Forward';
import Input from '#material-ui/core/Input';
import FormControl from '#material-ui/core/FormControl';
import Slide from '#material-ui/core/Slide';
const styles = theme => ({
dialogPaper: {
opacity: 0.5,
border: '#FF0000 1px solid',
},
button: {
margin: '30px'
}
});
function Transition(props) {
return <Slide direction="up" {...props} />;
}
class SignInDialog extends React.Component {
state = {
open: false,
username: ''
};
handleClickOpen = () => {
this.setState({ open: true });
};
handleClose = () => {
this.setState({ open: false });
};
handleChange = name => event => {
this.setState({
[name]: event.target.value,
});
};
render() {
const { classes } = this.props;
return (
<div>
<Button variant="fab" color="primary" aria-label="add" className={classes.button} onClick={this.handleClickOpen}>
<ForwardIcon />
</Button>
<Dialog
PaperProps={styles.dialogPaper}
open={this.state.open}
TransitionComponent={Transition}
onClose={this.handleClose}
aria-labelledby="form-dialog-title"
>
<DialogTitle id="form-dialog-title">WELCOME</DialogTitle>
<DialogContent>
<p>SIGN IN</p>
<FormControl className={classes.formControl}>
<Input
value={this.state.searchString}
onChange={this.handleChange('search')}
id="siginin-input"
placeholder="Enter your username"
/>
</FormControl>
</DialogContent>
<DialogActions>
<Button onClick={this.handleClose} color="primary">
Cancel
</Button>
<Button onClick={this.handleClose} color="primary">
Continue
</Button>
</DialogActions>
</Dialog>
</div>
);
}
}
SignInDialog.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(SignInDialog);
I haven't been able to figure out how to get the Dialog to take the styles. What is needed to get PaperProps to work?
If you want to use PaperProps you have to specify the props of the Paperfor which you are applying style.
<Dialog
PaperProps={{ classes: {root: classes.dialogPaper } }}
/>
You can also use classes property and override the style
<Dialog
classes={{paper:classes.dialogPaper}}
/>
The correct way to overide paper props is by using classNames
<Dialog
PaperProps={{ className: classNames(classes.dialogPaper) }}/>
<Dialog
PaperProps={{ classes: {root: classes.dialogPaper } }}
/>