# Scoped Hooks

Scoped hooks are **server hooks** tied to a page or form workflow. They are different from client-side lifecycle hooks such as `onFormLoad`; if you need the browser-side equivalents, see [Lifecycle Hooks](/reference/hooksoverview/lifecycle-hooks.md).

### onUtility

By far the most common type of scoped hook! This hook is called with the [**runUtilityHook** action](/reference/actions-processor/actions_overview/runutilityhook.md) like so:

```yaml
{
  "action": "runUtilityHook",
  "options": {
    "type": "save"
  }
}
```

In BetterForms you can differentiate buttons by passing a different value in the `options.type` key. Then, in FileMaker parse out the options object from the $$BF\_Payload and branch the script accordingly.

```javascript
JSONGetElement ( $$BF_Payload ; "data.hookPackage.options.type" )
```

### onFieldValidationHook

This hook is called when a field has been assigned an `fmsHook` validator.

The `.validation` object is broken out for you in the var `$validation` You can make business logic decisions based on the data here. The rest of the other objects are also available including `$actions` so you can inject workflow changes too.

To pass back validation error messages set the `validation.error` element to your error message.

| .validation Object | Type                | Description                                                                                                              |
| ------------------ | ------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| validation.value   | string              | The value of the single field that is requesting validation.                                                             |
| validation.field   | { object }          | This is the formSchema field object, this can be used to identify what field is requesting validation.                   |
| validation.model   | { object }          | This is the data model for the object(s) requesting validation. This is not needed currently but present for future use. |
| *validation.error* | { string or array } | This is passed back to the server and the contents are displayed as error messages.                                      |

## Wizard Forms

The following hooks only apply the pages of the "wizard" type. The are called on special cases, but otherwise function just like the [onUtility](#onutility) hook type.

#### onTabChange

This hook is run if the **Run onTabChange Script Hook** is enabled for a wizard form.

#### onComplete

This is run when the user clicks the **Complete** button for a wizard form.

### Additional Submission options

There are times you want to run actions prior to calling server side scripts. If an optional `wizardOnComplete_actions` key has bee set in the form ( misc tab) then those actions will be run in place of the `onComplete` script hook. You will have to call a utility hook within your actions for server side logic.

## Related Pages

* [Script Hooks](/reference/hooksoverview.md)
* [Common Hooks](/reference/hooksoverview/commonoverview.md)
* [Lifecycle Hooks](/reference/hooksoverview/lifecycle-hooks.md)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.klai.studio/reference/hooksoverview/hooks.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
