How to disable formik form after submission of form?

I have created a formik form that stores values at the backend. I have set-reset button, initial values. Everything working fine. But I can’t able to find a way to disable formik form after submission of the form i.e if the user fills the form after a click on submit button user is not able to click on the text field.

// @ts-ignore
import React, { useState, useEffect } from 'react';
import { Formik, Form, Field } from 'formik';
import { Typography, Button, Grid } from '@material-ui/core';
import * as Yup from 'yup';
import { MyInput } from './comman/MyInput';
import { Textarea } from './comman/Textarea';
import { Event } from '../Tracking/Event';
const contactSchema = Yup.object().shape({
name: Yup.string().required('Please Enter Your Name'),
email: Yup.string()
.email('Please enter a valid email address')
.required('Please enter an email address'),
number: Yup.string()
.min(10, 'Must be 10 digit.')
.max(10, 'Must be 10 digit.'),
});
export default function ContactUs(props: any) {
const [submitted,setSubmittde] = useState(false);
const [state, setState] = useState({
msg: '',
});
const [selectedemail, setEmail] = useState({
text: '',
});
const [comname, setComname] = useState({
cName: '',
});
useEffect(() => {
fetch(`${window.location.href}`);
//const findemail = window.location.href;
const findemail =
'public/home';
const email =
findemail.match(/([a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+.[a-zA-Z0-9_-]+)/) ||
[];
const finalemail = email[0].toString();
const company = findemail.match(/(?<=%)w+(?=&)/g) || [];
const finalcompany = company.toString();
setComname({ cName: finalcompany });
setEmail({ text: finalemail });
}, []);
return (
<div>
<img
src="public/logo"
width="200"
className="d-inline-block"
alt="logo"
style={{
marginTop: '2em',
marginBottom: '2em',
float: 'right',
}}
/>
<Formik
enableReinitialize
initialValues={{
name: '',
email: selectedemail.text,
number: '',
companyname: comname.cName,
message: '',
}}
validationSchema={contactSchema}
onSubmit={(values, { resetForm }) => {
const data = {
name: values.name,
email: values.email,
number: values.number,
companyname: values.companyname,
message: values.message,
formtype: 'Email Marketing Contactus',
};
const request = new Request(
`${process.env.REACT_APP_PRODUCTION_EMAILCONTACTUS_API}`,
{
method: 'POST',
headers: new Headers({
'Content-Type': 'application/json',
}),
body: JSON.stringify(data),
},
);
fetch(request)
.then((res) => res.json())
.then((data) => {
if (
data.message ===
'We have received your message and will get in touch shortly. Thanks!'
) {
setState({
msg: data.message,
});
} else {
console.log('error');
}
});
resetForm();
}}
>
{({ errors, touched }) => (
<Grid container>
<Grid item xs={12}>
<Typography
variant="body1"
style={{
marginTop: '1em',
fontFamily: 'roboto',
fontSize: '1.3rem',
color: '#2F4858',
}}
>
To know more please submit your information, and one of our
expert advisors will get in touch within 24 hours!{' '}
</Typography>
<br />
<Form>
<Typography
variant="h6"
style={{
fontFamily: 'roboto',
color: '#2F4858',
marginTop: '0.5em',
}}
>
Full Name
</Typography>
<Field
id="outlined-multiline-flexible"
type="text"
name="name"
placeholder="Name"
component={MyInput}
/>
<br />
{errors.name && touched.name ? (
<div className="text-danger" style={{ color: 'red' }}>
{errors.name}
</div>
) : null}
<Typography
variant="h6"
style={{ fontFamily: 'roboto', marginTop: '1em' }}
>
Email
</Typography>
<Field
type="email"
name="email"
placeholder="Email"
values={props.text}
style={{ color: 'white' }}
component={MyInput}
/>{' '}
<br />
{errors.email && touched.email ? (
<div className="text-danger" style={{ color: 'red' }}>
{errors.email}
</div>
) : null}
<Typography
variant="h6"
style={{
fontFamily: 'roboto',
color: '#2F4858',
marginTop: '1em',
}}
>
Mobile Number (Optional)
</Typography>
<Field
name="number"
placeholder="Contact Number"
component={MyInput}
// label="Contact Number"
/>
<br />
{errors.number && touched.number ? (
<div className="text-danger" style={{ color: 'red' }}>
{errors.number}
</div>
) : null}
<Typography
variant="h6"
style={{
fontFamily: 'roboto',
color: '#2F4858',
marginTop: '1em',
}}
>
Company Name (Optional)
</Typography>
<Field
name="companyname"
placeholder="Company Name"
// label="Contact Number"
component={MyInput}
/>
<br />
<Typography
variant="h6"
style={{
fontFamily: 'roboto',
color: '#2F4858',
marginTop: '1em',
}}
>
How can we help? (Optional)
</Typography>
<Field
id="outlined-multiline-static"
name="message"
placeholder="Your question about our services"
label="How can we help?"
component={Textarea}
/>
<br />
<br />
<Button
type="submit"
variant="contained"
onClick={() =>
Event(
'Contact from',
'Client submitted ',
'domain',
)
}
style={{
background: '#F79924',
color: 'white',
fontFamily: 'roboto',
fontSize: '1rem',
}}
>
Submit{' '}
</Button>
<br />
{state.msg && (
<Typography
variant="h6"
style={{
color: '#4BB543',
fontFamily: 'roboto-medium',
marginTop: '1em',
}}
>
{' '}
{state.msg}{' '}
</Typography>
)}
</Form>
</Grid>
</Grid>
)}
</Formik>
</div>
);
}

[![Formik form][1]][1]

I don’t know how to disable formik form. Please help? [1]: https://i.stack.imgur.com/PQXBV.png

Answer

This can be simply done using the disabled attribute and your existing value isSubmitted.

Pass a prop disabled into your custom input:

<Field
type="email"
name="email"
placeholder="Email"
values={props.text}
style={{ color: 'white' }}
component={MyInput}
disabled={isSubmitted}
/>

And apply it in the custom input using the ...props spread:

const MyInput = ({
field,
label,
name,
id,
value,
...props
}) => (
<div>
<label htmlFor="id">{label} </label>
<input id={id} type="text" {...field} {...props} />
</div>
);

And make sure you set isSubmitted somewhere in the onSubmit function

fetch(request)
.then((res) => res.json())
.then((data) => {
if (
data.message ===
'We have received your message and will get in touch shortly. Thanks!'
) {
setState({
msg: data.message,
});
setIsSubmitted(true);
} else {
console.log('error');
}
});

Live demo of a simple form that disables inputs/button after submission.