Formik handleReset is going through validation - reactjs

I'm trying to add a Reset button on my Formik form. Trouble is, when I click the Reset button Formik shows me the validation errors. Only after I click the Reset button a second time does the form actually reset. Why should the user go through form validation if all they want is to reset the form, right? Here's my form component:
const ContactForm = () => {
const submit = async (values, { setSubmitting, resetForm }) => {
... submit logic ...
}
return (
<Formik
initialValues={{
name: '',
email: '',
message: '',
}}
validationSchema={Yup.object({
name: Yup.string()
.min(3, 'Tamanho mínimo: 3 caracteres')
.max(20, 'Tamanho máximo: 20 caracteres')
.required('Campo obrigatório.'),
...more fields ...
})}
onSubmit={submit}
>
{({ isValid, isSubmitting, handleReset }) => (
<Form>
<div className="mb-3">
<label htmlFor="name" className="form-label">
Nome
</label>
<Field
name="name"
type="text"
className="form-control"
aria-describedby="nameHelp"
/>
<ErrorMessage
component="div"
id="nameHelp"
name="name"
className="form-text text-warning"
/>
</div>
... more fields ...
<button
type="submit"
disabled={isSubmitting || !isValid}
className="btn btn-primary shadow me-3"
>
Enviar
</button>
<button
disabled={isSubmitting}
className="btn btn-outline-primary shadow"
onClick={handleReset}
>
Apagar
</button>
</Form>
)}
</Formik>
)
}
export default ContactForm
I must be doing something wrong. How can I reset the form without going through the validation process?

I think you should update your reset button as follows -
<button type="reset" onClick={ e => formik.resetForm()}> Reset</button>

Related

Form data filled does not show on console using react hooks

I have a form built with formik and yup, but after filling the form, the data did not show on the console and when i clicked the next button, it does not take to the next page.
The validations are working.
.
.
.
const navigate = useNavigate()
const initialValues = {
phone: "",
email: ""
}
const validationSchema = Yup.object({
phone: Yup.string().required('Required'),
email: Yup.string().required('Required').email('Invalid email format'),
})
const onSubmit = values => {
console.log('Form data', values)
navigate("/NextPage")
}
<Formik
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={onSubmit}>
<Form>
<div className="mb-3">
<label className='form-label'>Phone Number</label><br/>
<Field type='tel' name='phone' className='place-holder white-bg' id='phone'/>
<ErrorMessage name='phone'>
{ (errorMsg) => <div className='error'>{errorMsg}</div> }
</ErrorMessage>
</div>
<div className="mb-3">
<label className='form-label'>Email address(optional)</label><br/>
<Field type='email' name='email' className='place-holder white-bg' id='email'/>
<ErrorMessage name='email'>
{ (errorMsg) => <div className='error'>{errorMsg}</div> }
</ErrorMessage>
</div>
<Button variant="primary" type="submit" className="buy-token-next-btn">
Next
</Button>
</Form>
</Formik>

React showing value required on edit case even if the field is already populated

I am using react-hook-form and Joi for the validataion in react. But in case of edit, if I don't touch any field and hit directly update, it shows value required, even when the field is already populated there.
But, once I focus or clicked on the input field, and hit update, then its get updated.
Here is the form:
const MarketplaceForm = ({ submitAction, submitBtnText, item }) => {
//joi schema
const schema = Joi.object({
name: Joi.string().required().min(3).max(191).label("Marketplace Name"),
});
//react hook form setup
const {
register,
handleSubmit,
setError,
clearErrors,
formState: { errors },
} = useForm({
resolver: joiResolver(schema),
});
const onSubmit = async (input) => {
submitAction(input, setError);
};
return (
<div className="intro-y box p-5">
<form id="add_marketplace_form" onSubmit={handleSubmit(onSubmit)}>
<div>
<label htmlFor="crud-form-1" className="form-label">
Marketplace Name
</label>
<input
className={`form-control w-full ${
errors["name"] ? "border-red-500" : ""
}`}
type="text"
id="name"
name="name"
autoComplete="on"
{...register("name")}
defaultValue={item.name ?? ""}
/>
<ErrorSpan errors={errors} fieldName="name" />
</div>
<div className="text-right mt-5">
<button
type="button"
className="btn btn-outline-secondary w-24 mr-1"
>
Cancel
</button>
<button type="submit" className="btn btn-success w-24">
{submitBtnText}
</button>
</div>
</form>
</div>
);
};
export default MarketplaceForm;
I guess you should check validation as your validation is not working properly or see the name props
is this default value working
defaultValue={item.name ?? ""}

Yup required validation not working and not giving error for empty field

I'm working on a form using formik and yup. I have added required schema, but it is not working. I can easily save having empty input fields. I have tried and googled but nothing worked.
I want to make it mandatory and it should give error if field is empty.
snippet of yup schema validation
opening_time: Yup.string().required("Opening time is Requried"),
closing_time: Yup.string().required("Closing time is Requried"),
address: Yup.string().required("Address is Requried"),
about: Yup.string().required("About is Required"),
Input field snippet
<div class="form-group mb-0">
<label>
About<span className="text-danger">*</span>
</label>
<textarea
name="about"
onChange={formik.handleChange}
value={formik.values.about}
class="form-control"
rows="5"
required
/>
{formik.touched.about && formik.errors.about ? (
<div className="err">
{formik.errors.about}
{console.log(formik.errors.about)}
</div>
) : null}
</div>
Try the following:
import React from 'react';
import { Formik, Form, Field } from 'formik';
import * as Yup from 'yup';
const SignupSchema = Yup.object().shape({
opening_time: Yup.string().required("Opening time is Requried"),
closing_time: Yup.string().required("Closing time is Requried"),
address: Yup.string().required("Address is Requried"),
about: Yup.string().required("About is Required"),
});
function ValidationSchemaExample() {
function updateDoctorProfile(e, values) {
console.log(`e: ${e}`);
console.log(`values: ${values}`)
}
return (
<div>
<h1>Signup</h1>
<Formik
initialValues={{
opening_time: "",
closing_time: "",
address: "",
about: "",
}}
validationSchema={SignupSchema}
onSubmit={values => {
// same shape as initial values
console.log(values);
}}
>
{({ values, errors, touched, handleChange, handleSubmit, isSubmitting }) => (
< div className="form-group mb-0">
<label>
About<span className="text-danger">*</span>
</label>
<textarea
name="about"
onChange={handleChange}
value={values.about}
className="form-control"
required
/>
<button type="submit" onClick={(e) => {
handleSubmit();
updateDoctorProfile(e, values);
}} disabled={isSubmitting}>
Submit
</button>
{touched.about && errors.about ? (
<div className="err">
{errors.about}
{console.log(errors.about)}
</div>
) : null}
</div>
)}
</Formik>
</div >
);
}
export default ValidationSchemaExample;
The only change is that the button tag's onClick attribute is passed the handleSubmit function along with your updateProfile function.

Antd form remote submit

I want to trigger the submit button outside the antd form
Here is my code
<Form
{...layout}
name="basic"
initialValues={{
remember: true,
}}
onFinish={onFinish}
onFinishFailed={onFinishFailed}
>
<Form.Item
label="Username"
name="username"
rules={[
{
required: true,
message: 'Please input your username!',
},
]}
>
<Input />
</Form.Item>
<Form.Item {...tailLayout}>
// Submit button here works well
</Form.Item>
</Form>
I want this outside form tag, please suggest
<Button type="primary" htmlType="submit">
Submit
</Button>
You can try this way:
const [form] = Form.useForm();
const handleFinish = (values) => {
console.log("values: ", values);
};
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<MyForm form={form} onFinish={handleFinish} />
<Button onClick={() => form.submit()}>Submit</Button>
</div>
);
export const MyForm = ({ form, onFinish }) => {
return (
<Form
form={form}
onFinish={onFinish}
initialValues={{ username: "John Doe" }}
>
<Form.Item name="username">
<Input />
</Form.Item>
</Form>
);
};
If the form and the button are not in the same component then it is hard to create same reference for the form in 2 different place. But I found an other easy way:
<Form id="myForm">...</>
...
<Button form="myForm" key="submit" htmlType="submit">
Submit
</Button>
This is the answer from this issue
write a custom function like this:
function handleSubmit(){
form.validateFields().then((values) => {
// do something with values
})
}
and call it from Button onClick. so you don't need Form onFinish props.
sorry i was searching and see this old question.
as in the comment you should use
const [form] = Form.useForm();
that's a lot of function you can use one of them is submit.
form.submit();
you can refer to document and search for useform:
https://ant.design/components/form/

How to disable button on submit form in formik?

I have a form in my react component with handleSubmit. What I need to do is when I submit the form(on save click) the save button automatically should get disabled and when I get the response it automatically gets enabled.
handleSubmit = async({ company, email }, { setSubmitting, setErrors }) => {
setSubmitting(true)
const { value: { status, message } } = await this.props.createCompany({ name: company, email })
if (status) {
this.fetchCompanies()
this.closeModal()
} else {
setErrors({ email: message })
}
}
<Formik
initialValues={loginDetails}
validationSchema={loginSchema}
onSubmit={(values, formikProps) => this.handleSubmit(values, formikProps)}
>
{({
values,
errors,
touched,
handleChange,
handleBlur,
handleSubmit,
isSubmitting
}) => (
<form onSubmit={handleSubmit}>
<div className="col-md-12">
<div className="form-group material-textfield">
<input type="text" name="email" value={values.email} onChange={handleChange} className="form-control material-textfield-input"/>
<ErrorMessage component="span" name="email" className="invalid-feedback d-block"/>
<label className="material-textfield-label">Email<span>*</span></label>
</div>
</div>
<button type="submit" className="btn btn-dark btn-lg w-100" disabled={isSubmitting}>Save</button>
</form>
)}
</Formik>
And for this I have used setSubmitting function from formik. But it doesn't work.
Kindly help.
This should help:
const onSubmitHandler = (values, formik) => {
persistYourData(values).then(r => {
formik.setSubmitting(false);
}).catch(error => console.log(error));
}
...
<Button variant="contained" color={"primary"} onClick={pr.handleSubmit} disabled={ ((!(pr.isValid && pr.dirty)) || pr.isSubmitting) }>Submit</Button>
#You can disable the button with **formik.isSubmitting** or **formik.errors** #
<Formik
initialValues={{
email: '',
password: '',
}}
validationSchema={Yup.object({
email: Yup.string().email('Invalid email address').required('Required'),
password: Yup.string().required('Required'),
})}
onSubmit={(values, { setSubmitting }) => {
setTimeout(() => {
alert(JSON.stringify(values, null, 2));
setSubmitting(false);
});
}}
>
{(formik) => (
<Form>
<h1>Login</h1>
<Field type='email' name='email' />
<br />
<ErrorMessage name='email' />
<br />
<Field type='password' name='password' />
<br />
<ErrorMessage name='password' />
<br />
<button disabled={formik.isSubmitting || formik.errors}>Login</button>
</Form>
)}
</Formik>

Resources