Skip to content

Form State API

Vorm provides full access to the internal form state through the useVorm() composable. It returns a powerful context object with reactive values and methods to interact with your form.

Basic Setup

ts
import { useVorm, type VormSchema } from 'vorm-vue';

const schema: VormSchema = [/* ... */];

const vorm = useVorm(schema, {
  validationMode: 'onBlur'  // 'onBlur' | 'onInput' | 'onSubmit'
});

Reactive State

Form Data

ts
vorm.formData          // Reactive form values
vorm.errors            // Error messages per field (string | null)
vorm.touched           // Whether field has been touched
vorm.dirty             // Whether field value has changed
vorm.initial           // Initial values at time of setFormData
vorm.validatedFields   // Which fields have been validated

Computed State

ts
vorm.isValid           // ComputedRef<boolean> - all validated fields pass
vorm.isDirty           // ComputedRef<boolean> - any field is dirty
vorm.isTouched         // ComputedRef<boolean> - any field is touched

Validation Methods

validateAll()

Validates all fields. Returns true if all pass:

ts
async function handleSubmit() {
  const isValid = await vorm.validateAll();
  if (isValid) {
    // Submit form
  }
}

validateFieldByName(name)

Validates a single field:

ts
await vorm.validateFieldByName('email');

getValidationMode(name)

Returns the validation trigger for a field:

ts
vorm.getValidationMode('email');  // 'onBlur' | 'onInput' | 'onSubmit'

Update Methods

updateField(name, value, options?)

Updates a single field with options:

ts
vorm.updateField('role', 'Admin', {
  touched: true,
  dirty: true,
  validate: true,
  fieldOptions: [
    { label: 'User', value: 'User' },
    { label: 'Admin', value: 'Admin' },
  ],
});

updateFields(updates, options?)

Update multiple fields at once:

ts
vorm.updateFields(
  { role: 'Admin', username: 'flo' },
  {
    touched: true,
    validate: true,
    fieldOptions: {
      role: [
        { label: 'User', value: 'User' },
        { label: 'Admin', value: 'Admin' },
      ],
    },
  }
);

setFormData(data, options?)

Replace entire form data and reset state:

ts
vorm.setFormData(
  { username: 'flo', role: 'Moderator' },
  {
    fieldOptions: {
      role: [
        { label: 'User', value: 'User' },
        { label: 'Moderator', value: 'Moderator' },
      ],
    },
  }
);

resetForm()

Clears all values, errors, and state:

ts
vorm.resetForm();

Error Methods

clearErrors()

Clears all validation errors:

ts
vorm.clearErrors();

clearError(name)

Clears error for a specific field:

ts
vorm.clearError('email');

getErrors()

Returns a copy of current errors:

ts
const errors = vorm.getErrors();

Options Methods

getFieldOptions(name)

Returns resolved options for a select field:

ts
const options = vorm.getFieldOptions('country');
// Returns ComputedRef<Option[]>

bindField(name)

Returns all bindings needed for custom components:

ts
const bindings = vorm.bindField('country');
// Returns ComputedRef<{
//   modelValue: any;
//   'onUpdate:modelValue': (v) => void;
//   items: Option[];
//   options: Option[];
//   error: string | undefined;
//   errorMessages: string[];
// }>

Usage with Vuetify:

vue
<v-select v-bind="vorm.bindField('country').value" />

Repeater Methods

addRepeaterItem(path, item?, index?)

Add item to repeater (default: end):

ts
vorm.addRepeaterItem('contacts', { name: '', email: '' });
vorm.addRepeaterItem('contacts', { name: '' }, 0);  // Insert at index 0

removeRepeaterItem(path, index)

Remove item by index:

ts
vorm.removeRepeaterItem('contacts', 2);

moveRepeaterItem(path, from, to)

Reorder repeater items:

ts
vorm.moveRepeaterItem('contacts', 0, 2);  // Move first to third position

clearRepeater(path)

Empty the repeater:

ts
vorm.clearRepeater('contacts');

Utility Methods

touchAll()

Marks all fields as touched:

ts
vorm.touchAll();

getTouched() / getDirty()

Returns copies of state maps:

ts
const touchedFields = vorm.getTouched();
const dirtyFields = vorm.getDirty();

Complete Example

vue
<script setup lang="ts">
import { useVorm, type VormSchema, minLength } from 'vorm-vue';
import { VormProvider, AutoVorm } from 'vorm-vue';

const schema: VormSchema = [
  {
    name: 'email',
    type: 'email',
    label: 'Email',
    validation: [{ rule: 'required' }, { rule: 'email' }],
  },
  {
    name: 'password',
    type: 'password',
    label: 'Password',
    validation: [{ rule: 'required' }, { rule: minLength(8) }],
  },
];

const vorm = useVorm(schema, { validationMode: 'onBlur' });

async function handleSubmit() {
  const isValid = await vorm.validateAll();
  if (isValid) {
    console.log('Submitting:', vorm.formData);
  }
}

function handleReset() {
  vorm.resetForm();
}
</script>

<template>
  <VormProvider :vorm="vorm">
    <AutoVorm as="form" @submit="handleSubmit">
      <div class="buttons">
        <button type="submit" :disabled="!vorm.isValid.value">Submit</button>
        <button type="button" @click="handleReset">Reset</button>
      </div>
    </AutoVorm>
  </VormProvider>

  <!-- Debug info -->
  <pre>{{ { isValid: vorm.isValid.value, isDirty: vorm.isDirty.value } }}</pre>
</template>

The useVorm() context is your gateway to dynamic form behavior, programmatic control, and granular state access.

MIT Licensed