# Mobx React Form Options

> Form and field options for mobx-react-form — validation timing, error display, strict modes, debounce, data retrieval, and per-field overrides.

- **Type:** Skill
- **Install:** `agentstack add skill-foxhound87-skills-mobx-react-form-options`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [foxhound87](https://agentstack.voostack.com/s/foxhound87)
- **Installs:** 0
- **Category:** [Search](https://agentstack.voostack.com/c/search)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [foxhound87](https://github.com/foxhound87)
- **Source:** https://github.com/foxhound87/skills/tree/main/mobx-react-form-options

## Install

```sh
agentstack add skill-foxhound87-skills-mobx-react-form-options
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Skill: mobx-react-form-options

## Mission

Guide the user through configuring **form and field options** in mobx-react-form to control validation timing, error display, strictness, data retrieval, and other behavioral settings.

Use this skill when the user needs to:
- Configure validation timing (on init, blur, change, submit)
- Control when errors are shown/hidden
- Enable strict mode for field selection/set/delete
- Configure data retrieval filters
- Set per-field options that override form-level defaults
- Customize debounce behavior

## Options Overview

Options can be set at:
1. **Form level** — applies to all fields
2. **Field level** — overrides form level for a specific field

## Validation Timing

| Option | Default | Description |
|--------|---------|-------------|
| `validateOnInit` | `true` | Validate entire form on initialization |
| `validateOnSubmit` | `true` | Validate on submit |
| `validateOnBlur` | `true` | Validate on field blur |
| `validateOnChange` | `false` | Validate on every keystroke |
| `validateOnChangeAfterInitialBlur` | `false` | Validate on change after first blur |
| `validateOnChangeAfterSubmit` | `false` | Validate on change after first submit |
| `validateOnClear` | `false` | Validate on clear |
| `validateOnReset` | `false` | Validate on reset |

```javascript
const options = {
  validateOnInit: true,
  validateOnChange: true,  // real-time validation
  validateOnBlur: false,
};
```

## Error Display

| Option | Default | Description |
|--------|---------|-------------|
| `showErrorsOnInit` | `false` | Show errors on init |
| `showErrorsOnSubmit` | `true` | Show errors on submit |
| `showErrorsOnBlur` | `true` | Show errors on blur |
| `showErrorsOnChange` | `true` | Show errors on change |
| `showErrorsOnClear` | `false` | Show errors on clear |
| `showErrorsOnReset` | `false` | Show errors on reset |

```javascript
const options = {
  showErrorsOnBlur: true,   // show error after field loses focus
  showErrorsOnChange: false, // don't show errors while typing
  showErrorsOnSubmit: true,  // show all on submit
};
```

## Strict Modes

| Option | Default | Description |
|--------|---------|-------------|
| `strictSelect` | `true` | Throw error if selecting undefined field |
| `strictSet` | `false` | Throw error if setting undefined field |
| `strictDelete` | `true` | Throw error if deleting undefined field |
| `strictUpdate` | `false` | Throw error if updating undefined field |

```javascript
const options = {
  strictSelect: false, // allow selecting fields that may not exist (for computed props)
};
```

> **Note**: `strictSelect: false` is required when using computed field props that access fields before they exist.

## Field Validation Scope

| Option | Default | Description |
|--------|---------|-------------|
| `validateDisabledFields` | `false` | Validate disabled fields |
| `validateDeletedFields` | `false` | Validate soft-deleted fields |
| `validatePristineFields` | `true` | Validate pristine (unchanged) fields |
| `validateTrimmedValue` | `false` | Trim value before validation |
| `stopValidationOnError` | `false` | Stop after first validation driver error |
| `resetValidationBeforeValidate` | `true` | Reset validation state before re-validating |
| `validationPluginsOrder` | `undefined` | Array of plugin names in execution order |
| `validationDebounceWait` | `250` | Debounce wait (ms) |
| `validationDebounceOptions` | `{ leading: false, trailing: true }` | Lodash debounce options |

```javascript
const options = {
  validateDisabledFields: false,
  validatePristineFields: false, // only validate touched fields
  stopValidationOnError: true,
  validationPluginsOrder: ['vjf', 'dvr'], // VJF first, then DVR
  validationDebounceWait: 500, // wait 500ms before validating
};
```

## Data Retrieval

| Option | Default | Description |
|--------|---------|-------------|
| `retrieveOnlyDirtyFieldsValues` | `false` | Get only changed field values |
| `retrieveOnlyEnabledFieldsValues` | `false` | Get only enabled field values |
| `retrieveOnlyEnabledFieldsErrors` | `false` | Get only enabled field errors |
| `removeNullishValuesInArrays` | `false` | Remove null/undefined/"" from arrays |
| `retrieveNullifiedEmptyStrings` | `false` | Convert empty strings to null |
| `preserveDeletedFieldsValues` | `false` | Preserve values after delete+add |

```javascript
const options = {
  retrieveOnlyDirtyFieldsValues: true, // only send changed fields on submit
  removeNullishValuesInArrays: true,
};

// Usage:
form.values(); // only returns dirty field values
```

## Value Handling

| Option | Default | Description |
|--------|---------|-------------|
| `fallback` | `true` | Allow field creation from values without struct definition |
| `fallbackValue` | `""` | Default fallback value |
| `defaultGenericError` | `null` | Default generic error message |
| `submitThrowsError` | `true` | Throw error on failed validation submit |
| `autoTrimValue` | `false` | Auto-trim string values |
| `autoParseNumbers` | `false` | Auto-parse strings to numbers |
| `softDelete` | `false` | Soft delete (mark deleted instead of removing) |
| `bubbleUpErrorMessages` | `false` | Error getter returns first nested error |

```javascript
const options = {
  autoParseNumbers: true, // "123" → 123 for number-typed fields
  autoTrimValue: true,    // "  hello  " → "hello"
  softDelete: true,       // del() marks field.deleted = true
  fallbackValue: null,    // use null as default empty value
  bubbleUpErrorMessages: true, // form.error shows first nested error
};
```

## Apply Input Converter

| Option | Default | Description |
|--------|---------|-------------|
| `applyInputConverterOnInit` | `true` | Apply input converter on field creation |
| `applyInputConverterOnSet` | `true` | Apply input converter on set() |
| `applyInputConverterOnUpdate` | `true` | Apply input converter on update() |

```javascript
const options = {
  applyInputConverterOnInit: true,
  applyInputConverterOnSet: false, // allow raw values via set()
  applyInputConverterOnUpdate: false,
};
```

## Other Options

| Option | Default | Description |
|--------|---------|-------------|
| `uniqueId` | built-in | Custom function to generate field IDs (useful for SSR) |

```javascript
const options = {
  uniqueId: (field) => `custom-${field.path}-${Date.now()}`,
};
```

## Setting Options

### Via constructor

```javascript
const form = new Form({ fields }, {
  options: {
    validateOnChange: true,
    showErrorsOnBlur: true,
    strictSelect: false,
  },
});
```

### Via extended class

```javascript
class MyForm extends Form {
  options() {
    return {
      validateOnChange: true,
      autoParseNumbers: true,
      retrieveOnlyDirtyFieldsValues: true,
    };
  }
}
```

### After initialization

```javascript
form.state.options.set({
  validateOnInit: false,
  validateOnChange: true,
  strictUpdate: true,
});
```

### Getting options

```javascript
// Get all options
form.state.options.get();

// Get single option
form.state.options.get('validateOnChange'); // true
```

## Per-Field Options

Each field can override form-level options:

```javascript
const fields = {
  email: {
    label: 'Email',
    rules: 'required|email',
    options: {
      validateOnChange: true,        // validate on every keystroke
      validateOnBlur: false,         // skip blur validation
      showErrorsOnChange: true,      // show errors immediately
      validationDebounceWait: 100,   // faster debounce for this field
    },
  },
  password: {
    label: 'Password',
    rules: 'required|min:6',
    options: {
      validateOnChange: false,       // don't validate while typing
      validateOnBlur: true,          // validate on blur
      showErrorsOnBlur: true,
    },
  },
};
```

### Per-field options in separated mode

```javascript
const options = {
  email: {
    validateOnChange: true,
    validateOnBlur: false,
  },
  password: {
    validateOnChange: false,
    validateOnBlur: true,
  },
};

new Form({ fields, options });
```

## Common Option Presets

### Real-time validation

```javascript
const options = {
  validateOnChange: true,
  validateOnBlur: false,
  showErrorsOnChange: true,
  validationDebounceWait: 300,
};
```

### Submit-only validation

```javascript
const options = {
  validateOnInit: false,
  validateOnChange: false,
  validateOnBlur: false,
  validateOnSubmit: true,
  showErrorsOnSubmit: true,
};
```

### Lazy validation (on blur, then on change)

```javascript
const options = {
  validateOnBlur: true,
  validateOnChangeAfterInitialBlur: true, // validates on change after first blur
  showErrorsOnBlur: true,
  showErrorsOnChange: true,
};
```

### Server-friendly data retrieval

```javascript
const options = {
  retrieveOnlyDirtyFieldsValues: true,
  removeNullishValuesInArrays: true,
  retrieveNullifiedEmptyStrings: true,
  autoTrimValue: true,
};
```

## Key Takeaways

1. **Three levels**: Form-level, constructor-provided, and per-field options.
2. **Field overrides form**: Each field can have its own `options` object.
3. **Validation timing**: Control when validation runs (init, change, blur, submit).
4. **Error display**: Show/hide errors independently from validation.
5. **Strictness**: `strictSelect: false` is required for computed props.
6. **Data filters**: `retrieveOnlyDirtyFieldsValues` etc. control `values()` output.
7. **Debounce**: Globally configurable via `validationDebounceWait`.
8. **Post-init changes**: Use `form.state.options.set({...})` at any time.

## Related Skills

- [mobx-react-form-api](../mobx-react-form-api/SKILL.md) — Core API prerequisite
- [mobx-react-form-validation](../mobx-react-form-validation/SKILL.md) — Validation options
- [mobx-react-form-flat](../mobx-react-form-flat/SKILL.md) — Field definitions with per-field options

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [foxhound87](https://github.com/foxhound87)
- **Source:** [foxhound87/skills](https://github.com/foxhound87/skills)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-foxhound87-skills-mobx-react-form-options
- Seller: https://agentstack.voostack.com/s/foxhound87
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
