Touched & dirty

Get fields and form touched and dirty status

Touched and dirty state

form.isTouched and form.isDirty fields provide information about current field status:

  • Field is considered to be touched when user focused it or its value was changed programmatically with form.setFieldValue handler
  • Field is considered to be dirty when its value was changed and new value is different from field value specified in initialValues (compared with fast-deep-equal)

Touched: not touched

Dirty: not dirty

import { useForm } from '@mantine/form';
import { TextInput, Text, Box } from '@mantine/core';

function Demo() {
  const form = useForm({ initialValues: { text: 'initial value' } });

  return (
    <Box maw={400} mx="auto">
      <TextInput
        {...form.getInputProps('text')}
        label="Touched/dirty demo"
        placeholder="Touched/dirty demo"
      />

      <Text size="sm" mt="sm">
        Touched:{' '}
        <Text span c={form.isTouched('text') ? 'blue' : 'red'}>
          {form.isTouched('text') ? 'touched' : 'not touched'}
        </Text>
      </Text>

      <Text size="sm">
        Dirty:{' '}
        <Text span c={form.isDirty('text') ? 'blue' : 'red'}>
          {form.isDirty('text') ? 'dirty' : 'not dirty'}
        </Text>
      </Text>
    </Box>
  );
}

isTouched and isDirty functions

import { useForm } from '@mantine/form';

const form = useForm({ initialValues: { a: 1, nested: { field: '' } } });

// Provide path as first argument to get state of 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 field path is not provided,
// then functions will return form state instead
form.touched(); // -> was any field in form focused or changed?
form.isDirty(); // -> was any field in form modified?

Initial values

You can provide initial touched and dirty values with initialTouched and initialDirty properties. Both properties support the same fields path format as errors:

import { useForm } from '@mantine/form';

const form = useForm({
  initialValues: { a: 1, nested: { field: '' } },
  initialTouched: { a: true, 'nested.field': true },
  initialDirty: { a: true, 'nested.field': true },
});

resetTouched and resetDirty

form.resetTouched and form.resetDirty functions will make all fields clean and untouched. Note that form.reset will also reset touched and dirty state:

import { useForm } from '@mantine/form';

const form = useForm({
  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 values that are used for dirty check call form.resetDirty with new values:

import { useForm } from '@mantine/form';

const form = useForm({
  initialValues: { a: 1 },
});

form.setValues({ a: 2 });
form.isDirty(); // -> true

form.resetDirty({ a: 2 });
form.isDirty(); // -> false

form.setValues({ a: 3 });
form.isDirty(); // -> true