# useSubmitActionTriggers

URL: https://docs.forms.saastro.io/docs/use-submit-action-triggers
> Fires submit actions automatically on field change, field blur, step transitions, and idle timeout.

# useSubmitActionTriggers

Manages automatic execution of submit actions based on non-submit triggers like field changes, blur events, step transitions, and idle timeouts. This is what powers real-time features like auto-saving on field change or sending analytics on step exit.

> **You probably don't need this directly.** The `<Form>` component wires it up internally whenever your config has `submitActions`. Use it when building custom trigger logic on top of your own form.

---

## Signature

```tsx

const { triggerFieldChange, triggerFieldBlur, triggerManual, hasActionsForTrigger } =
  useSubmitActionTriggers({
    config,
    getValues,
    currentStep,
    onActionExecuted,
    onActionError,
    enabled,
  });
```

---

## Parameters

| Parameter          | Type                              | Required | Description                                                                                       |
| ------------------ | --------------------------------- | -------- | ------------------------------------------------------------------------------------------------- |
| `config`           | `FormConfig`                      | Yes      | Form configuration with submit actions                                                            |
| `getValues`        | `() => Record<string, unknown>`   | Yes      | Function returning the current form values — pass `methods.getValues` itself (avoids re-renders) |
| `currentStep`      | `string`                          | Yes      | Active step ID                                                                                    |
| `onActionExecuted` | `(result) => void`                | No       | Called after an action completes                                                                  |
| `onActionError`    | `(error, actionName) => void`     | No       | Called when an action fails                                                                       |
| `enabled`          | `boolean`                         | No       | Enable/disable all triggers (default: `true`)                                                     |

> `getValues` is a **function reference**, not a values object. Pass `methods.getValues` directly — do not call it (`methods.getValues()`). The hook reads values lazily at fire time, so triggers always see the latest data without subscribing to every keystroke.

---

## Return Value

| Property               | Type                                           | Description                                   |
| ---------------------- | ---------------------------------------------- | --------------------------------------------- |
| `triggerFieldChange`   | `(fieldName, value) => void`                   | Trigger `onFieldChange` actions (debounced)   |
| `triggerFieldBlur`     | `(fieldName) => void`                          | Trigger `onFieldBlur` actions (immediate)     |
| `triggerManual`        | `(actionIds?) => Promise<SubmitActionsResult>` | Manually trigger specific actions             |
| `hasActionsForTrigger` | `(triggerType, triggerValue?) => boolean`      | Check if any actions exist for a trigger type |

---

## Trigger Types

| Trigger         | When It Fires                   | Behavior                                                      |
| --------------- | ------------------------------- | ------------------------------------------------------------- |
| `onFieldChange` | User changes a field value      | Debounced (`debounceMs` of the first matching action, default 300ms, per field) |
| `onFieldBlur`   | User leaves a field             | Immediate                                                     |
| `onStepEnter`   | User navigates to a step        | Automatic (via step change detection)                         |
| `onStepExit`    | User leaves a step              | Automatic (via step change detection)                         |
| `onDelay`       | User is idle for `delayMs` ms (default 30000) | Automatic (listens to mousedown, keydown, touchstart, scroll; re-arms after each activity) |
| `manual`        | Programmatic trigger            | Via `triggerManual()` call                                    |

> **`onSubmit` actions are not handled by this hook** — they run inside the submit pipeline when the form is submitted. `hasActionsForTrigger('onSubmit')` still reports them.

---

## Example: Manual Trigger

```tsx

function SaveDraftButton({ config }: { config: FormConfig }) {
  const { methods, currentStepId } = useFormState({ config, fields: config.fields });

  const { triggerManual, hasActionsForTrigger } = useSubmitActionTriggers({
    config,
    getValues: methods.getValues, // pass the function, don't call it
    currentStep: currentStepId,
  });

  const saveDraft = async () => {
    // Check if there are manual actions available
    if (hasActionsForTrigger('manual')) {
      const result = await triggerManual(['save-draft']);
      console.log('Draft saved:', result.allSuccessful);
    }
  };

  return <button onClick={saveDraft}>Save draft</button>;
}
```

---

## Notes

- `triggerManual` ignores `enabled` — it executes even when `enabled` is `false`. The automatic effects and `triggerFieldChange`/`triggerFieldBlur` do respect it.
- `triggerFieldChange` ignores its `value` argument; values are read via `getValues()` when the debounced action actually fires.
- The hook's option and return interfaces are not exported types — only the function itself is public.
- All debounce and idle timers are cleared on unmount.

---

## Related

- [Submit & Actions](/docs/submit) — Configuring submit actions with different triggers
