Skip to content

Commit

Permalink
Allow forced validation to run anywhere
Browse files Browse the repository at this point in the history
  • Loading branch information
jaredpalmer committed Dec 12, 2019
1 parent b2fecda commit 83d33a9
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 28 deletions.
8 changes: 4 additions & 4 deletions docs/api/formik.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,13 +154,13 @@ use it to pass API responses back into your component in `handleSubmit`.

Set `isSubmitting` imperatively. You would call it with `setSubmitting(false)` in your `onSubmit` handler to finish the cycle. To learn more about the submission process, see [Form Submission](guides/form-submission.md).

#### `setTouched: (fields: { [field: string]: boolean }) => void`
#### `setTouched: (fields: { [field: string]: boolean }, shouldValidate?: boolean) => void`

Set `touched` imperatively.
Set `touched` imperatively. Calling this will trigger validation to run if `validateOnBlur` is set to `true` (which it is by default). You can also explicitly prevent/skip validation by passing a second argument as `false`.

#### `setValues: (fields: { [field: string]: any }) => void`
#### `setValues: (fields: { [field: string]: any }, shouldValidate?: boolean) => void`

Set `values` imperatively.
Set `values` imperatively. Calling this will trigger validation to run if `validateOnChange` is set to `true` (which it is by default). You can also explicitly prevent/skip validation by passing a second argument as `false`.

#### `status?: any`

Expand Down
48 changes: 28 additions & 20 deletions packages/formik/src/Formik.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -505,23 +505,31 @@ export function useFormik<Values extends FormikValues = FormikValues>({
delete fieldRegistry.current[name];
}, []);

const setTouched = useEventCallback((touched: FormikTouched<Values>) => {
dispatch({ type: 'SET_TOUCHED', payload: touched });
return validateOnBlur
? validateFormWithLowPriority(state.values)
: Promise.resolve();
});
const setTouched = useEventCallback(
(touched: FormikTouched<Values>, shouldValidate?: boolean) => {
dispatch({ type: 'SET_TOUCHED', payload: touched });
const willValidate =
shouldValidate === undefined ? validateOnBlur : shouldValidate;
return willValidate
? validateFormWithLowPriority(state.values)
: Promise.resolve();
}
);

const setErrors = React.useCallback((errors: FormikErrors<Values>) => {
dispatch({ type: 'SET_ERRORS', payload: errors });
}, []);

const setValues = useEventCallback((values: Values) => {
dispatch({ type: 'SET_VALUES', payload: values });
return validateOnChange
? validateFormWithLowPriority(values)
: Promise.resolve();
});
const setValues = useEventCallback(
(values: Values, shouldValidate?: boolean) => {
dispatch({ type: 'SET_VALUES', payload: values });
const willValidate =
shouldValidate === undefined ? validateOnChange : shouldValidate;
return willValidate
? validateFormWithLowPriority(values)
: Promise.resolve();
}
);

const setFieldError = React.useCallback(
(field: string, value: string | undefined) => {
Expand All @@ -534,15 +542,17 @@ export function useFormik<Values extends FormikValues = FormikValues>({
);

const setFieldValue = useEventCallback(
(field: string, value: any, shouldValidate: boolean = true) => {
(field: string, value: any, shouldValidate?: boolean) => {
dispatch({
type: 'SET_FIELD_VALUE',
payload: {
field,
value,
},
});
return validateOnChange && shouldValidate
const willValidate =
shouldValidate === undefined ? validateOnChange : shouldValidate;
return willValidate
? validateFormWithLowPriority(setIn(state.values, field, value))
: Promise.resolve();
}
Expand Down Expand Up @@ -618,19 +628,17 @@ export function useFormik<Values extends FormikValues = FormikValues>({
);

const setFieldTouched = useEventCallback(
(
field: string,
touched: boolean = true,
shouldValidate: boolean = true
) => {
(field: string, touched: boolean = true, shouldValidate?: boolean) => {
dispatch({
type: 'SET_FIELD_TOUCHED',
payload: {
field,
value: touched,
},
});
return validateOnBlur && shouldValidate
const willValidate =
shouldValidate === undefined ? validateOnBlur : shouldValidate;
return willValidate
? validateFormWithLowPriority(state.values)
: Promise.resolve();
}
Expand Down
8 changes: 4 additions & 4 deletions packages/formik/src/types.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,9 @@ export interface FormikHelpers<Values> {
/** Manually set isSubmitting */
setSubmitting(isSubmitting: boolean): void;
/** Manually set touched object */
setTouched(touched: FormikTouched<Values>): void;
setTouched(touched: FormikTouched<Values>, shouldValidate?: boolean): void;
/** Manually set values object */
setValues(values: Values): void;
setValues(values: Values, shouldValidate?: boolean): void;
/** Set value of form field directly */
setFieldValue(field: string, value: any, shouldValidate?: boolean): void;
/** Set error message of a form field directly */
Expand Down Expand Up @@ -123,15 +123,15 @@ export interface FormikHandlers {
/** Preact-like linkState. Will return a handleBlur function. */
handleBlur<T = string | any>(
fieldOrEvent: T
): T extends string ? ((e: any) => void) : void;
): T extends string ? (e: any) => void : void;
/** Classic React change handler, keyed by input name */
handleChange(e: React.ChangeEvent<any>): void;
/** Preact-like linkState. Will return a handleChange function. */
handleChange<T = string | React.ChangeEvent<any>>(
field: T
): T extends React.ChangeEvent<any>
? void
: ((e: string | React.ChangeEvent<any>) => void);
: (e: string | React.ChangeEvent<any>) => void;

getFieldProps<Value = any>(props: any): FieldInputProps<Value>;
getFieldMeta<Value>(name: string): FieldMetaProps<Value>;
Expand Down

0 comments on commit 83d33a9

Please sign in to comment.