apps/mantine.dev/src/pages/form/status.mdx
import { FormDemos } from '@docs/demos'; import { Layout } from '@/layout'; import { MDX_DATA } from '@/mdx';
export default Layout(MDX_DATA.formStatus);
form.isTouched and form.isDirty fields provide information about the current field status:
touched when the user focused it or its value was changed programmatically with the form.setFieldValue handlerdirty when its value was changed and the new value is different from the field value specified in initialValues (compared with fast-deep-equal)import { useForm } from '@mantine/form';
const form = useForm({
mode: 'uncontrolled',
initialValues: { a: 1, nested: { field: '' } },
});
// Provide path as the first argument to get the state of a single field
form.isTouched('a'); // -> was field 'a' focused or changed?
form.isDirty('a'); // -> was field 'a' modified?
form.isDirty('nested.field'); // -> nested fields are also supported
// If the field path is not provided,
// then the functions will return the form state instead
form.isTouched(); // -> was any field in the form focused or changed?
form.isDirty(); // -> was any field in the form modified?
The touchTrigger option allows customizing events that change the touched state.
It accepts two options:
change (default) – the field will be considered touched when its value changes or it has been focusedfocus – the field will be considered touched only when it has been focusedExample of using focus trigger:
import { useForm } from '@mantine/form';
const form = useForm({
mode: 'uncontrolled',
initialValues: { a: 1 },
touchTrigger: 'focus',
});
form.isTouched('a'); // -> false
form.setFieldValue('a', 2);
form.isTouched('a'); // -> false
// onFocus is called automatically when the user focuses the field
form.getInputProps('a').onFocus();
form.isTouched('a'); // -> true
You can provide initial touched and dirty values with the initialTouched and initialDirty properties.
Both properties support the same field path format as errors:
import { useForm } from '@mantine/form';
const form = useForm({
mode: 'uncontrolled',
initialValues: { a: 1, nested: { field: '' } },
initialTouched: { a: true, 'nested.field': true },
initialDirty: { a: true, 'nested.field': true },
});
The form.resetTouched and form.resetDirty functions will make all fields clean and untouched.
Note that form.reset will also reset the touched and dirty state:
import { useForm } from '@mantine/form';
const form = useForm({
mode: 'uncontrolled',
initialValues: { a: 1 },
initialTouched: { a: true },
initialDirty: { a: true },
});
form.isDirty('a'); // -> true
form.isTouched('a'); // -> true
form.resetTouched();
form.isTouched('a'); // -> false
form.resetDirty();
form.isDirty('a'); // -> false
To reset the values that are used for the dirty check, call form.resetDirty with new values:
import { useForm } from '@mantine/form';
const form = useForm({
mode: 'uncontrolled',
initialValues: { a: 1 },
});
form.setValues({ a: 2 });
form.isDirty(); // -> true
form.resetDirty({ a: 2 });
form.isDirty(); // -> false
form.setValues({ a: 3 });
form.isDirty(); // -> true
The form.submitting field will be set to true if the function passed to
form.onSubmit returns a promise. After the promise is resolved or rejected,
form.submitting will be set to false:
You can also manually set form.submitting to true or false:
import { useForm } from '@mantine/form';
const form = useForm({ mode: 'uncontrolled' });
form.submitting; // -> false
form.setSubmitting(true);
form.submitting; // -> true
form.setSubmitting(false);
form.submitting; // -> false
The form.validating property is true while any async validation is in
progress. This applies to form.validate(), form.validateField(),
form.isValid(), and the validation triggered by form.onSubmit.
form.isValidating(path) returns true if a specific field is currently being
validated. When form.validate() or form.onSubmit runs all rules, every field
with a rule is considered validating. When form.validateField(path) is called,
only the targeted field is considered validating.
import { useForm } from '@mantine/form';
const form = useForm({
mode: 'uncontrolled',
initialValues: { username: '' },
validate: {
username: async (value) => {
// simulate an API call
await new Promise((resolve) => setTimeout(resolve, 500));
return value === 'admin' ? 'Username is taken' : null;
},
},
});
form.validating; // -> false while idle, true during validation
form.isValidating('username'); // -> true while `username` rule is running