Unable to reset value in State of React - reactjs

export default function Register() {
const [formData, setformData] = useState({
name: "",
emailid: "",
password: "",
password2: "",
});
const [formHelperText, setFormHelperText] = useState({
formHelperTextname: "",
formHelperTextemailid: "",
formHelperTextpassword: "",
formHelperTextpassword2: "",
});
const { name, emailid, password, password2 } = formData;
const {
formHelperTextname,
formHelperTextemailid,
formHelperTextpassword,
formHelperTextpassword2,
} = formHelperText;
const onChange = (e) => {
setformData({ ...formData, [e.target.name]: e.target.value });
};
let onSubmit = (e) => {
e.preventDefault();
debugger;
var mailformat = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+#[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/;
setFormHelperText({
...formHelperText,
formHelperTextname: "",
formHelperTextemailid: "",
});
if (name.length === 0) {
setFormHelperText({
...formHelperText,
formHelperTextname: "Enter your name",
});
}
else if (emailid.length === 0) {
setFormHelperText({
...formHelperText,
formHelperTextemailid: "Enter your email",
});
} else if (!emailid.match(mailformat)) {
setFormHelperText({
...formHelperText,
formHelperTextemailid: "Enter valid email",
});
}
};
return (
<Container component="main" maxWidth="xs">
<CssBaseline />
<div className={classes.paper}>
<Avatar className={classes.avatar}>
<LockOutlinedIcon />
</Avatar>
<Typography component="h1" variant="h5">
Sign up
</Typography>
<form className={classes.form} noValidate onSubmit={onSubmit}>
<TextField
variant="outlined"
margin="normal"
required
fullWidth
id="name"
label="Name"
name="name"
value={name}
onChange={onChange}
autoFocus
error={formHelperTextname.length > 0}
helperText={formHelperTextname}
/>
<TextField
variant="outlined"
margin="normal"
required
fullWidth
id="email"
label="Email Address"
name="emailid"
value={emailid}
onChange={onChange}
autoComplete="email"
error={formHelperTextemailid.length > 0}
helperText={formHelperTextemailid}
/>
<TextField
variant="outlined"
margin="normal"
required
fullWidth
name="password"
label="Password"
type="password"
id="password"
value={password}
onChange={onChange}
error={formHelperTextpassword.length > 0}
helperText={formHelperTextpassword}
/>
<TextField
variant="outlined"
margin="normal"
required
fullWidth
name="password2"
label="Retype Password"
type="password"
id="password2"
value={password2}
onChange={onChange}
error={formHelperTextpassword2.length > 0}
helperText={formHelperTextpassword2}
/>
<Button
type="submit"
fullWidth
variant="contained"
color="primary"
className={classes.submit}
>
Sign Up
</Button>
<Grid container>
<Grid item xs></Grid>
<Grid item>
<Link href="/" variant="body2">
{"Already have an account? Sign In"}
</Link>
</Grid>
</Grid>
</form>
</div>
</Container>
);
}
When I'm trying to reset the value of formHelperTextname onSubmit function. The value is not updating to an empty string.
The value is set inside the IF condition but before the if condition when I try to reset the value of formhelperText it's not working
When I'm trying to reset the value of formHelperTextname onSubmit function. The value is not updating to an empty string.
The value is set inside the IF condition but before the if condition when I try to reset the value of formhelperText it's not working

States cannot be assigned immediately after they are changed. It is necessary to listen to State and do the same.
You can review the revised code below.
I hope I helped.
const [isClear, setIsClear] = useState(false);
useEffect(() => {
if (isClear) {
setFormHelperText({
...formHelperText,
formHelperTextname: "",
formHelperTextemailid: "",
});
}
}, [isClear]);
let onSubmit = (e) => {
e.preventDefault();
debugger;
var mailformat = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+#[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/;
setIsClear(true);
if (name.length === 0) {
setFormHelperText({
...formHelperText,
formHelperTextname: "Enter your name",
});
}
else if (emailid.length === 0) {
setFormHelperText({
...formHelperText,
formHelperTextemailid: "Enter your email",
});
} else if (!emailid.match(mailformat)) {
setFormHelperText({
...formHelperText,
formHelperTextemailid: "Enter valid email",
});
}
};

Related

I want to use onBlur here but I'm making some mistake

Here I want to use onBlur function here but the way I want is whenever I enter the email it should activate onBlur and whenever it is empty the input field should hide it but I'm not getting exact solution for this. Here is the code that I have used..
const [user, update_user] = useState({
user_name: "",
email: "",
clearUser: false,
clearEmail: false,
});
const clearValue = (key, show) => {
update_user({ ...user, [key]: "", [show]: false });
};
const [showSecondInput, setShowSecondInput] = useState(false);
const handleOTP = (e) => {
const { name:key, value } = e.target;
if(key=== "email") setShowSecondInput({ ...showSecondInput, [key]: "", clearEmail: true })
else
setShowSecondInput({...showSecondInput,[key]:"", clearEmail:false});
};
Here is the return/ main code
<Input
fullWidth
name="email"
value={user.email}
onChange={handleChange}
disableUnderline={true}
onBlur={handleOTP}
className={classes.inputEmail}
endAdornment={
<>
{user.clearEmail ? (
<IconButton
onClick={() => clearValue("email", "clearEmail")}
>
<ClearIcon />
</IconButton>
) : (
""
)}
</>
}
/>
{showSecondInput && (
<>
<Typography
color="#05445E"
fontFamily="'Jost', sans-serif"
fontSize={15}
sx={{ mt: "5px" }}
>
Enter OTP
</Typography>
<Input
className={classes.inputEmail}
fullWidth
type="password"
/>
</>
)}

React formik Validation Error Api Renders Every Time when other field validate

I've created a register form I tried to validate the form onBlur and the one has an email check with backend Apis, I have an issue when I validate any other that case mail check API render every time
I tried with onBlur and onChange validation false that case working fine, But I need onBlur validation, Any Ideas
Thanks for Help
const CompanyRegister = (props) => {
const classes = useStyles();
var [mailError, setMailError] = useState(false);
const initialValues = {
name: "",
website: "",
addressLine1: "",
city: "",
state: "",
mail: "",
};
const validationSchema = yup.object({
name: yup.string().strict().trim().required("Enter the ComapnyName"),
website: yup
.string()
.matches(
/((https?):\/\/)?(www.)?[a-z0-9]+(\.[a-z]{2,}){1,3}(#?\/?[a-zA-Z0-9#]+)*\/?(\?[a-zA-Z0-9-_]+=[a-zA-Z0-9-%]+&?)?$/,
"Enter correct url!"
)
.strict()
.trim()
.required("Enter the Website"),
pincode: yup.number("Invalid pincode").positive("Invalid pincode"),
phone: yup.number("InValid Phone Number"),
altPhone: yup.number("InValid Phone Number"),
mail: yup
.string()
.email("Enter correct Format")
.strict()
.trim()
.required("Enter the Correct Email"),
});
const validCheck = (data) => {
var mailData = { mail: data };
axios.post(baseurl + "companymailcheck", mailData).then((res) => {
if (res.data == "Invalid") {
setMailError(true);
} else {
setMailError(false);
}
});
};
const onSubmit = (data) => {
axios
.post(baseurl + "companyregisteration", data)
.then((res) => {
history.push(`/login`);
toast.success("Successfully Created");
})
.catch((err) => {
toast.error("Some Thing Error");
});
};
return (
<>
<div className={classes.back}>
<Link to="/">Home</Link>
</div>
<Container component="main" className={classes.layout}>
<div className={classes.paper}>
<Typography component="h1" variant="h5">
Register
</Typography>
<Formik
initialValues={initialValues}
onSubmit={onSubmit}
validateOnChange={false}
validateOnBlur={true}
validationSchema={validationSchema}
>
{({ values, isValid }) => {
return (
<Form autoComplete="off">
<Grid container spacing={4}>
<Grid item xs={12} sm={6}>
<Field
as={TextField}
name="name"
fullWidth
label="Company Name"
autoFocus
required
/>
<ErrorMessage name="name">
{(error) => (
<div className={classes.error}>{error}</div>
)}
</ErrorMessage>
</Grid>
<Grid item xs={12} sm={6}>
<Field
as={TextField}
name="website"
fullWidth
label="Website"
required
/>
<ErrorMessage name="website">
{(error) => (
<div className={classes.error}>{error}</div>
)}
</ErrorMessage>
</Grid>
<Grid item xs={12} sm={12}>
<Field
as={TextField}
name="addressLine1"
type="text"
fullWidth
label="Address Line1"
/>
</Grid>
<Grid item xs={12} sm={6}>
<Field
as={TextField}
name="mail"
fullWidth
label="Mail"
required
validate={() => validCheck(values.mail)}
/>
<ErrorMessage name="mail">
{(error) => (
<div className={classes.error}>{error}</div>
)}
</ErrorMessage>
{mailError ? (
<span style={{ color: "red" }} id="errormessage">
Mail Already There!
</span>
) : null}
</Grid>
<Button
type="submit"
fullWidth
variant="contained"
color="primary"
className={classes.submit}
disabled={!isValid || mailError}
>
Register
</Button>
</Grid>
</Form>
);
}}
</Formik>
</div>
</Container>
</>
);
};
export default CompanyRegister;
As long as it's fine to perform the validation during form submission then I would extend the onSubmit and put the check there.
You can use the second parameter which will return the FormikBag containing all relevant setter's to invalidate the form-field properly. Reference: https://formik.org/docs/api/formik#onsubmit-values-values-formikbag-formikbag--void--promiseany
In this case I would use setFieldError(field, message). Reference: https://formik.org/docs/api/formik#setfielderror-field-string-errormsg-string--void
<Formik initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={(values, {setFieldError}) => {
return validateMail(values.mail)
.then(() => {
// all good - continue with your submit handler
return onSubmit(values)
})
.catch(error => {
// something wrong? validate the error response + validation message OR set it statically.
setFieldError('mail', 'Mail Already There!')
})
}}
>

How can I pass email displaying in DialogContentText to axios put request

How can I pass ratePlyrEmail to calculateAvgRating() during on click on submit button.
The player email will displays randomly in the <Input type="hidden" name="playertorate" value={email} onChange={onChange}></Input> of DialogContentText every time when the user click on Enter Player Rating button. I have added onChange in the DialogContentText. Now I am getting only rating and loginUserEmail in server side.
const [ratePlyrEmail, setRatePlyrEmail] = useState({ playertorate: ''});
const [rating, setRating] = useState({
shooting: "",
dribbling: "",
ballcontrol: "",
sprinting: "",
fitness: ""
});
const [ratingTotal, setRatingTotal] = useState(0);
const onChange = e => {
e.persist();
const ratingValues = {
...rating,
[e.target.name]: e.target.value
};
setRating(ratingValues);
const rateEmailValue = {
...ratePlyrEmail,
[e.target.name]: e.target.value
}
setRatePlyrEmail(rateEmailValue);
ratingCalculation(ratingValues);
};
const ratingCalculation = ratingValues =>{
const {
shooting,
dribbling,
ballcontrol,
sprinting,
fitness
} = ratingValues;
const newTotal =
Number(shooting) +
Number(dribbling) +
Number(ballcontrol) +
Number(sprinting) +
Number(fitness);
const finalAvg = newTotal / 5;
setRatingTotal(finalAvg);
return ratingTotal ;
}
const calculateAvgRating = (rating) => {
const sendPlayerRating = async () => {
try {
const params = {
email: loginUserEmail,
};
const res = await axios.put('http://localhost:8000/service/playerrating', {ratingTotal:rating}, {params} );
if (res.data.success) {
//rest of code to continue here...
}
else {
console.log(res.data.message);
}
} catch (e) {
console.log(e.response.data.message);
}
}
sendPlayerRating();
};
<div className="container">
<div className="weeklycount_graph_section">
<div>
<Button className="playerRatingBtn" variant="outlined" color="primary" onClick={() => handleClickOpen(setRandPlayerRating())}>
Enter Player Rating
</Button>
<Dialog
open={open}
onClose={handleClose}
aria-labelledby="skills-area"
>
<DialogTitle id="skills-area">Rate the skills of a player</DialogTitle>
<DialogContent>
{
randPlayers.map(({email, name, photo}) =>(
<DialogContentText key="id">
<Avatar alt="player" src={photo}/>
<Input type="hidden" name="playertorate" value={email} onChange={onChange}></Input>
</DialogContentText>
))
}
<TextField
autoFocus
onChange={onChange}
margin="dense"
name="shooting"
label="Shooting"
type="text"
fullWidth
/>
<TextField
autoFocus
onChange={onChange}
margin="dense"
name="dribbling"
label="Dribbling"
type="text"
fullWidth
/>
<TextField
autoFocus
onChange={onChange}
margin="dense"
name="ballcontrol"
label="Ball Control"
type="text"
fullWidth
/>
<TextField
autoFocus
onChange={onChange}
margin="dense"
name="sprinting"
label="Sprinting"
type="text"
fullWidth
/>
<TextField
autoFocus
onChange={onChange}
margin="dense"
name="fitness"
label="Fitness"
type="text"
fullWidth
/>
</DialogContent>
<DialogActions>
<Button onClick={handleClose} color="secondary">
Cancel
</Button>
<Button onClick={() => handleClose(calculateAvgRating((ratingCalculation(rating))))} color="primary">
Submit
</Button>
</DialogActions>
</Dialog>
</div>
</div>
</div>

Formik number field accept only positive numbers

I have a form in which I have a number field. I am using formik for this. I need to have an input which only accepts positive numbers.
This is the codesandbox url
You should use regex in onChange event of Number input
Sample code:
const App = () => (
<div className="app">
<Formik
initialValues={{ email: "", rank: -2 }}
onSubmit={async values => {
await new Promise(resolve => setTimeout(resolve, 500));
alert(JSON.stringify(values, null, 2));
}}
validationSchema={Yup.object().shape({
email: Yup.string()
.email()
.required("Required")
})}
>
{props => {
const {
values,
touched,
errors,
dirty,
isSubmitting,
handleChange,
handleBlur,
handleSubmit,
handleReset,
setFieldValue
} = props;
return (
<form onSubmit={handleSubmit}>
<label htmlFor="email" style={{ display: "block" }}>
Email
</label>
<input
id="email"
placeholder="Enter your email"
type="text"
value={values.email}
onChange={handleChange}
onBlur={handleBlur}
className={
errors.email && touched.email
? "text-input error"
: "text-input"
}
/>
<label htmlFor="email" style={{ display: "block" }}>
Rank
</label>
<input
id="rank"
placeholder="Enter your email"
type="number"
value={values.rank}
onChange={e => {
e.preventDefault();
const { value } = e.target;
const regex = /^(0*[1-9][0-9]*(\.[0-9]*)?|0*\.[0-9]*[1-9][0-9]*)$/;
if (regex.test(value.toString())) {
setFieldValue("rank", value);
}
}}
onBlur={handleBlur}
/>
<button type="submit" disabled={isSubmitting}>
Submit
</button>
</form>
);
}}
</Formik>
</div>
);
render(<App />, document.getElementById("root"));
Code sanbox link: https://codesandbox.io/embed/formik-example-nut8p?fontsize=14&hidenavigation=1&theme=dark
You can add the attribute min to your input
<input
id="rank"
placeholder="Enter your rank"
type="number"
value={values.rank}
min="1"
onChange={handleChange}
onBlur={handleBlur}
/>
Pass a validate function
// Synchronous validation
const validate = values => {
const errors = {};
if (!values.numberFied < 0) {
errors.numberFied = 'Must be positive';
}
//...
return errors;
};

Login Form validation in Reactjs : material ui <textfield>

I am trying to do login form validation in my react app. I am new to react and I am using Material UI. So I try to enter the data in the login and password fields but I am not able to. Could someone tell me what exactly is the problem? Is it because I declared the data object in state? Following is the code:
state = {
open: false,
show: null,
dialogOpen: false,
buttonDisabled: true,
data: {
email: "",
password: ""
},
errors: {}
};
handleChange = e =>
this.setState({
data: { ...this.state.data, [e.target.name]: e.target.value }
});
onSubmit = () => {
const errors = this.validate(this.state.data);
this.setState({ errors });
};
validate = data => {
const errors = {};
if (!Validator.isEmail(data.email)) errors.email = "Invalid email";
if (!data.password) errors.password = "Can't be blank";
return errors;
};
const { data, errors } = this.state;
<Dialog open={this.state.dialogOpen} onClose={this.closeDialog} >
<DialogTitle>Login</DialogTitle>
<DialogContent>
<DialogContentText>
Please enter your Login data here
</DialogContentText>
<form onSubmit={this.onSubmit}>
<TextField
margin="dense"
id="email"
label="Email Address"
className={classes.textField}
type="email"
value={data.email}
onChange={this.handleChange}
fullWidth
/>
{errors.email && <InlineError text={errors.email} />}
<TextField
margin="dense"
id="password"
label="Password"
className={classes.textField}
type="password"
value={data.password}
onChange={this.handleChange}
fullWidth
/>
{errors.password && <InlineError text={errors.password} />}
<Button
className={classes.button}
onClick={this.clickLogin}
color="primary"
>
Enter
</Button>
</form>
</DialogContent>
</Dialog>
the issue that i noticed with your code is that you are targeting name attribute which you didn't create. so make the following adjustment to your code
handleChange = e =>
this.setState({
data: { ...this.state.data, [e.target.id]: e.target.value }
});
onSubmit = () => {
const errors = this.validate(this.state.data);
this.setState({ errors });
};
In the above code, i used e.target.id which can be referenced correctly in the textField.

Resources