-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Optionally show multiple validation errors per field #1573
base: next
Are you sure you want to change the base?
Conversation
… errors for a given field at once
Do we really need an additional configuration prop for this? I believe you can set (or resolve errors while validating) like this. <Formik
validate={values => doYourYupValidationMagicAndReturnErrors(values)}
/> |
@Andreyco Yes, that works fine for |
@mbrowne were you ever able to merge this in? thanks, |
Hello! @jaredpalmer I absolutely LOVE this library! @mbrowne Thank you for making this pull request! Is this, or something similar to this functionality arriving in the library soon? I would love to have the support and ability to provide context for multiple different errors at a time without having to re-declare everything in the Thank you for all the hard work! Please keep it up! |
👍 |
in the meantime, here's a userland solution to make this work today, based on the code of this PR: https://codesandbox.io/s/formik-example-forked-wxzl1?file=/index.js // Helper styles for demo
import "./helper.css";
import React from "react";
import { render } from "react-dom";
import { Formik, validateYupSchema, setIn, getIn } from "formik";
import * as Yup from "yup";
// Copied from PR: https://github.com/formium/formik/pull/1573
/**
* Transform Yup ValidationError to a more usable object
*/
export function yupToFormErrors(yupError, validationSchemaOptions) {
let errors = {};
if (yupError.inner.length === 0) {
return setIn(errors, yupError.path, yupError.message);
}
// if showMultipleFieldErrors is enabled, set the error value
// to an array of all errors for that field
if (validationSchemaOptions.showMultipleFieldErrors) {
for (let err of yupError.inner) {
let fieldErrors = getIn(errors, err.path);
if (!fieldErrors) {
fieldErrors = [];
}
fieldErrors.push(err.message);
errors = setIn(errors, err.path, fieldErrors);
}
} else {
for (let err of yupError.inner) {
if (!errors[err.path]) {
errors = setIn(errors, err.path, err.message);
}
}
}
return errors;
}
const validateYupSchemaMultiErrors = async (values, schema) => {
try {
await validateYupSchema(values, schema);
return {};
} catch (e) {
return yupToFormErrors(e, { showMultipleFieldErrors: true });
}
};
const PasswordSchema = Yup.object().shape({
password: Yup.string()
.matches(/[a-z]/, "company.users.edit.form.errors.lowercase")
.matches(/[\d]{1}/, "company.users.edit.form.errors.digit")
.matches(/[A-Z]/, "company.users.edit.form.errors.uppercase")
.min(8, "company.users.edit.form.errors.min"),
});
const App = () => (
<div className="app">
<h1>
Basic{" "}
<a
href="https://github.com/jaredpalmer/formik"
target="_blank"
rel="noopener noreferrer"
>
Formik
</a>{" "}
Demo
</h1>
<Formik
initialValues={{ password: "" }}
onSubmit={async (values) => {
await new Promise((resolve) => setTimeout(resolve, 500));
alert(JSON.stringify(values, null, 2));
}}
validate={(values) =>
validateYupSchemaMultiErrors(values, PasswordSchema)
}
>
{(props) => {
const {
values,
touched,
errors,
handleChange,
handleBlur,
handleSubmit,
} = props;
console.log(props);
return (
<form onSubmit={handleSubmit}>
<input
id="password"
placeholder="Enter your password"
type="text"
value={values.password}
onChange={handleChange}
onBlur={handleBlur}
className={
errors.password && touched.password
? "text-input error"
: "text-input"
}
/>
{errors.password && touched.password && (
<div style={{ color: "red" }}>
{errors.password instanceof Array
? errors.password.map((error) => <div>{error}</div>)
: errors.password}
</div>
)}
</form>
);
}}
</Formik>
</div>
);
render(<App />, document.getElementById("root")); |
@slorber 's code works but here is my updated version based on my specifications:
This will solve the following:
|
This PR adds a new prop called
validationSchemaOptions
to add the feature described here:#243
Example usage:
showMultipleFieldErrors
is false by default, to maintain consistency with the current behavior of returning just a single string per field.