# os_events_reference

OS events are server-side scripts that control the behavior of enaio® clients and the server.
They are bound to object types or the entire application and executed when defined events occur.
Each event specifies the target platform (desktop client, server, web client), the UI context (data sheet, hit list, query, application), and the scripting language (JavaScript or VBScript).

### JSON Structure

Events are returned as a JSON object in the output parameter `JSON` (BASE64-encoded).
The root object contains the array `osevents` with one element per event:

```json
{
  "osevents": [
    {
      "id": 9,
      "event_code": 13,
      "os_class_name": "2",
      "object_class": 3,
      "app_class": 1,
      "is_js": false,
      "os_event_params": "B6ACC477B34F41D6BDBEBE13025F243B",
      "modify_user": "ROOT",
      "last_modified": 1774686279,
      "vb_code": "'OnClickButton"
    },
    {
      "id": 1,
      "event_code": 5000,
      "os_class_name": "Application",
      "object_class": 2,
      "app_class": 2,
      "is_js": true,
      "os_event_params": "krn.EmptyJob",
      "modify_user": "ROOT",
      "last_modified": 1752738837,
      "vb_code": "const value = rc.apps.inputParams.get(\"Status\").value;\nif (value !== \"freigegeben\") throw Error(\"Not approved.\");"
    },
    {
      "id": 38,
      "event_code": 10005,
      "os_class_name": "Application",
      "object_class": 2,
      "app_class": 2,
      "is_js": true,
      "os_event_params": "MyServerLibrary",
      "modify_user": "ROOT",
      "last_modified": 1774688890,
      "vb_code": "// Usage: const utils = require(\"MyServerLibrary\")\nfunction formatDate(ts) { return new Date(ts).toISOString().slice(0, 10); }\nmodule.exports = { formatDate };"
    }
  ]
}
```

### Fields

| Field | Type | Dependency | Description |
|---|---|---|---|
| [[dms-osevent-id]]`id` | integer | — | Internal database primary key of the event in the `osevents` table |
| [[dms-osevent-event-code]]`event_code` | integer | — | Event type — determines when the script is executed. +<br>Detail: <<dms-osevent-event-code-detail>> |
| [[dms-osevent-object-class]]`object_class` | integer | — | Numeric representation of the UI context (redundant to `event_code`). +<br>Mapping: <<dms-osevent-object-class-mapping>> |
| [[dms-osevent-app-class]]`app_class` | integer | — | Target platform (redundant to `event_code`): `1` = Client · `2` = Server · `3` = WebClient |
| [[dms-osevent-os-class-name]]`os_class_name` | string | — | Target object type: `"Application"` for server-/application-wide events, otherwise the `type_id` as a string. +<br>Detail: <<dms-osevent-os-class-name-detail>> |
| [[dms-osevent-is-js]]`is_js` | boolean | — | Scripting language: `true` = JavaScript · `false` = VBScript. +<br>Detail: <<dms-osevent-is-js-detail>> |
| [[dms-osevent-vb-code]]`vb_code` | string | — | Executable script code (JavaScript or VBScript). +<br>Detail: <<dms-osevent-vb-code-detail>> |
| [[dms-osevent-os-event-params]]`os_event_params` | string | Optional | Context parameter — content depends on the `event_code`. +<br>Mapping: <<dms-osevent-os-event-params-mapping>> |
| [[dms-osevent-modify-user]]`modify_user` | string | — | Login name of the enaio® user who last modified the event |
| [[dms-osevent-last-modified]]`last_modified` | integer | — | Unix timestamp of the last modification (seconds since 1970-01-01 UTC) |

#### Field `id`

Internal database primary key of the event in the `osevents` table. Unique per event instance.

Dependencies: none

#### Field `event_code`

Specifies the event type — i.e. **when** the script is executed. The value corresponds to the `eventcode` column in the `oseventcodes` table and can be resolved against it to determine the event name, UI context (`objectclass`), and target platform (`appclass`).

```sql
SELECT eventname, objectclass, appclass, descrshort
FROM oseventcodes
WHERE eventcode = <event_code>
```
Dependencies:

* Determines the meaning of `object_class` and `app_class`
* Determines the expected format of `os_event_params` (see <<dms-osevent-os-event-params-mapping>>)
* **Independent of `is_js`** — the `event_code` defines only the trigger point, not the scripting language. An `OnShow` event (code 1) is code 1 regardless of whether it is stored as VBScript or JavaScript. Exceptions: web client events (11000–11024) and `JavascriptLibrary` events (10005/10006) are always `is_js=true`.

Value ranges:

| Range | Name | Platform | Context |
|---|---|---|---|
| `1`–`43` | Standard client events | Client | Data sheet, hit list, query, application |
| `100`–`104` | Batch change events | Client | Batch change |
| `200` | Cabinet events | Client | Cabinet |
| `5000`–`5012` | Server events | Server | Application, server events |
| `10000`–`10006` | Global scripts & libraries | Client / Server | Object type, application |
| `11000`–`11024` | Web client events | WebClient | Data sheet, hit list, application |
```text
1      → OnShow             (Client / Data sheet)
13     → OnClickItem        (Client / Data sheet)
5000   → KernelBeforeJob    (Server / Application)
5002   → JoblBeforeObject   (Server / Server events)
10005  → JavascriptLibrary  (Server / Application)
11021  → OnAddLocation      (WebClient / Hit list)
```

#### Field `object_class`

Numeric representation of the UI context in which the event is triggered. Corresponds to the `objectclass` column in `oseventcodes`, but encoded as an integer. The value is **redundant** to `event_code` — it can be derived directly from it.

Dependencies: always consistent with `event_code`, no independent information beyond `event_code`.

| Value | Meaning |
|---|---|
| `1` | Query |
| `2` | Application (server-/application-wide) |
| `3` | Data sheet |
| `4` | Stored query (event_code 6, 7 — value derived from sequence, not directly observed) |
| `5` | Object type |
| `6` | Batch change |
| `7` | Cabinet |
| `8` | Server events |
| `9` | Hit list |
```text
3   → Event belongs to data sheet context (OnShow, BeforeValidate, …)
9   → Event belongs to hit list context (BeforeDelete, OnMove, …)
8   → Event belongs to server events context (JoblBeforeObject, JobAfterObject)
```

#### Field `app_class`

Specifies the target platform of the event — i.e. on which client type or the server the script is executed. Corresponds to the `appclass` column in `oseventcodes`, but encoded as an integer. Like `object_class`, it is redundant to `event_code`.

| Value | Meaning |
|---|---|
| `1` | Client (desktop client) |
| `2` | Server |
| `3` | WebClient |
```text
1   → Script runs in the desktop client
2   → Script runs on the server
3   → Script runs in the web client (always is_js=true)
```

#### Field `os_class_name`

Identifies the target object type to which the event is bound. The value is either the string `"Application"` (for server- or application-wide events) or a numeric string corresponding to the global `type_id` of an object type.

The `type_id` is derived internally as `(maintype << 16) | cotype` and can be resolved via [dms.GetObjDef](../dms.md#dms.GetObjDef). The returned asobjdef XML contains the internal name and the associated cabinet of the object type.

Dependencies:

* The determining factor is `object_class`: if it is `2` (Application), `os_class_name` contains `"Application"`; for other values (`3` data sheet, `5` object type, etc.), the field contains a `type_id`
* `GlobalObjectTypeScript` (event_code `10002`) is bound to a specific object type (`object_class=5`) — `os_class_name` contains a `type_id` here, even though `app_class=1` (client)
* `JavascriptLibrary Client` (event_code `10006`) has `object_class=2` (Application) — `os_class_name` is `"Application"` here, even though `app_class=1` (client)
* The rule of thumb "`app_class=1` → `type_id`" therefore does not apply in general

```text
"Application"   → server-/application-wide event (KernelBeforeJob, OnSessionLogin, …)
"2"             → type_id 2      → object type with internal name "DefinitionTests"
"6488064"       → type_id 6488064 → e.g. a register object type in another cabinet
"262144"        → type_id 262144  → e.g. a document object type
```

#### Field `is_js`

Specifies the scripting language of the code contained in `vb_code`.

| Value | Language | Runtime |
|---|---|---|
| `true` | JavaScript (ECMAScript) | enaio® JS engine (`rc` API) |
| `false` | VBScript | Legacy enaio® VBScript engine |
Dependencies:

* Web client events (`app_class=3`) are **always** `is_js=true`
* `JavascriptLibrary` events (code 10005/10006) are **always** `is_js=true`

```text
true   → JavaScript event, uses rc.apps.inputParams, rc.apps.outputParams, etc.
false  → VBScript event, legacy API
```

#### Field `vb_code`

Contains the executable script code of the event. Despite the field name `vb_code`, the content can be either VBScript (if `is_js=false`) or JavaScript (if `is_js=true`).

Dependencies:

* Scripting language is determined by `is_js`
* For JavaScript, the `rc` API is available (`rc.apps`, `rc.lib`, `rc.com`)
* For `JavascriptLibrary` events (code 10005/10006), the field contains reusable library code that is included via `require("<os_event_params>")`

#### Field `os_event_params`

Optional context parameter — the content depends on the `event_code`. The field is empty when no specific context is configured (e.g. for events that apply to the entire object type).

| Event code(s) | Event name(s) | Content | Meaning |
|---|---|---|---|
| `5000`, `5001` | `KernelBeforeJob`, `KernelAfterJob` | Job name | Script is executed only for this specific job |
| `5002`, `5003` | `JoblBeforeObject`, `JobAfterObject` | Job name | Script is executed only for this specific job |
| `13`, `102` | `OnClickItem` | Field GUID (button) | Resolvable via [dms.GetObjDef](../dms.md#dms.GetObjDef) → field with matching `osguid` |
| `32`, `39` | `OnFocusGained`, `OnCellFocusGained` | Field GUID | Resolvable via [dms.GetObjDef](../dms.md#dms.GetObjDef) → field with matching `osguid` |
| `33`, `40` | `OnValueChanged`, `OnCellValueChanged` | Field GUID | Resolvable via [dms.GetObjDef](../dms.md#dms.GetObjDef) → field with matching `osguid` |
| `25`, `37`, `103` | `OnEnterPage`, `OnLeavePage` | Field GUID (page control) | Resolvable via [dms.GetObjDef](../dms.md#dms.GetObjDef) → page control field with matching `osguid` |
| `10005`, `10006` | `JavascriptLibrary` | Library name | Name under which the library is included via `require("<library name>")` |
| all others | — | empty (`""`) | Event applies to the entire object type without field restriction |
GUIDs in `os_event_params` correspond to the `osguid` attribute of a field in the asobjdef XML retrieved via [dms.GetObjDef](../dms.md#dms.GetObjDef). The associated object type can be determined via `os_class_name` (→ `type_id`).

```text
""                                  → no specific UI element (applies to entire object type)
"krn.EmptyJob"                      → KernelBeforeJob: only when krn.EmptyJob is executed
"std.DoArchive"                     → JoblBeforeObject: only during archiving (std.DoArchive)
"B6ACC477B34F41D6BDBEBE13025F243B"  → GUID of a button field (OnClickItem)
"AD61A45160D24D9CB48E9F5BA399563D"  → GUID of an input field (OnFocusGained)
"329C7E04A5CC4BC3AFF2F8798808914A"  → GUID of a page control field (OnEnterPage / OnLeavePage)
"MyServerLibrary"                   → library name for server JavascriptLibrary
"MyClientLibrary"                   → library name for client JavascriptLibrary
```

#### Field `modify_user`

Login name of the enaio® user who last modified (created or changed) the event.

Dependencies: none

```text
"ROOT"
"admin"
"mustermann"
```

#### Field `last_modified`

Unix timestamp (seconds since 1970-01-01 UTC) of the time of the last modification of the event.

Dependencies: none

```text
1752738837   → 2025-07-17 07:53:57 UTC
1774686603   → 2026-03-28 08:30:03 UTC
```

### Event Codes

Event codes correspond to the `eventcode` column in the database table `oseventcodes` and can be resolved with the following query:

```sql
SELECT eventname, objectclass, appclass, descrshort
FROM oseventcodes
WHERE eventcode = <event_code>
```
> **Note:** The numbering of event codes is not sequential. Code `38` does not exist (sequence jumps from `37` to `39`). In the Global Scripts range, `10003` and `10004` do not exist (sequence jumps from `10002` to `10005`). These gaps are by design and not an error.

#### Standard Client Events (1–43) — Desktop Client

.Data Sheet
| Code | Name | Description |
|---|---|---|
| `1` | `OnShow` | After the data sheet has been opened and populated with values |
| `2` | `BeforeValidate` | Before data validation by the client |
| `3` | `AfterSave` | After successful saving |
| `13` | `OnClickItem` | When a menu item or button has been clicked |
| `25` | `OnEnterPage` | When a page of the page control is activated |
| `30` | `BeforeCancel` | Before cancelling the data sheet |
| `32` | `OnFocusGained` | When the input focus is set to a control |
| `33` | `OnValueChanged` | When input to a control has been completed |
| `34` | `BeforeAddRow` | Before a row is added to a list control |
| `35` | `BeforeDeleteRow` | Before a row is removed from a list control |
| `36` | `AfterValidate` | After data validation by the client |
| `37` | `OnLeavePage` | When another page of the page control is activated |
| `39` | `OnCellFocusGained` | When the focus is set to a cell of a table control |
| `40` | `OnCellValueChanged` | When input to a cell of a table control has been completed |
.Query
| Code | Name | Description |
|---|---|---|
| `4` | `BeforeStartQuery` | Before the actual query is executed |
.Hit List
| Code | Name | Description |
|---|---|---|
| `5` | `AfterFinishQuery` | After a query has been completed |
| `11` | `BeforeDelete` | Before an object is deleted |
| `12` | `AfterDelete` | After an object has been deleted |
| `16` | `BeforeOpen` | Before a document or folder is opened |
| `17` | `OnMove` | When an object is moved within a cabinet by drag & drop |
| `18` | `OnAddLocation` | When an object is copied by drag & drop and a new location is added |
| `19` | `BeforeSaveDocument` | Before sending the document to the application server |
| `20` | `AfterSaveDocument` | After sending the document to the application server |
| `27` | `BeforeUndoCheckOut` | Before "Undo check out" is executed on a document |
| `28` | `BeforeRestore` | Before an object is restored from the recycle bin |
| `29` | `AfterRestore` | After an object has been restored from the recycle bin |
| `42` | `OnMoveExtern` | When an object is moved to another cabinet by drag & drop |
| `43` | `OnCreateCopy` | When a copy of a document or register is created |
.Application
| Code | Name | Description |
|---|---|---|
| `6` | `BeforeStartRequest` | Before a stored query has been started |
| `7` | `AfterFinishRequest` | After a stored query has been completed |
| `8` | `AfterLogin` | After the user has logged in |
| `9` | `BeforeLogout` | Before the user logs out |
| `10` | `OnTime` | When a preset time is reached |
| `14` | `OnStartApp` | After the client has been fully initialized |
| `15` | `OnCloseApp` | Before the client is closed |
| `21` | `BeforeLink` | Before two objects are linked |
| `22` | `AfterLink` | After two objects have been linked |
| `23` | `BeforeDeleteLink` | Before two linked objects are unlinked |
| `24` | `AfterDeleteLink` | After two linked objects have been unlinked |
| `26` | `OnContextChanged` | After an entry in a hit list has been selected |
| `31` | `StartAction` | After a server notification |
| `41` | `BeforeOpenRelationDialog` | Before the relation dialog is opened |

#### Batch Change Events (100–104) — Desktop Client

| Code | Name | Description |
|---|---|---|
| `100` | `BeforeValidate` | Before data validation in the batch change |
| `101` | `OnShow` | After the batch change data sheet has been opened |
| `102` | `OnClickItem` | When a menu item or button has been clicked |
| `103` | `OnEnterPage` | When a page of the page control is activated |
| `104` | `AfterValidate` | After data validation in the batch change |

#### Cabinet Events (200) — Desktop Client

| Code | Name | Description |
|---|---|---|
| `200` | `FileDrop` | After dragging and dropping a file from the file system into a folder |

#### Server Events (5000–5012) — Server

| Code | Name | Context | Description |
|---|---|---|---|
| `5000` | `KernelBeforeJob` | Application | Before a job is executed |
| `5001` | `KernelAfterJob` | Application | After a job has been executed |
| `5002` | `JoblBeforeObject` | Server events | Before an object of a specific object type is processed |
| `5003` | `JobAfterObject` | Server events | After an object of a specific object type has been processed |
| `5004` | `BeforeStartArchiveBatch` | Application | Before an archive run begins |
| `5005` | `OnInitializeMedium` | Application | Before a medium is written to for the first time |
| `5006` | `BeforeOpenMedia` | Application | Before a medium is written to within an archive run |
| `5007` | `OnCloseMedia` | Application | After archiving to a medium has been completed |
| `5008` | `OnFinishMedia` | Application | After a medium has been permanently closed |
| `5009` | `OnFinishArchiveBatch` | Application | At the end of archiving |
| `5010` | `OnArchiveError` | Application | When an error is written to the rep file |
| `5011` | `OnObjectHistoryEntry` | Application | For each entry in an object's history |
| `5012` | `OnSessionLogin` | Application | For each login attempt |

#### Global Scripts & Libraries (10000–10006) — Client / Server

| Code | Name | Platform | Description |
|---|---|---|---|
| `10000` | `GlobalClientScript` | Client | Appended to every other client script |
| `10001` | `GlobalServerScript` | Server | Appended to every other server script |
| `10002` | `GlobalObjectTypeScript` | Client | Appended to every object type |
| `10005` | `JavascriptLibrary` | Server | Reusable JS library, includable via `require("<library name>")` |
| `10006` | `JavascriptLibrary` | Client | Reusable JS library, includable via `require("<library name>")` |

#### Web Client Events (11000–11024) — WebClient

.Data Sheet
| Code | Name | Description |
|---|---|---|
| `11000` | `OnShow` | After the data sheet has been opened and populated with values |
| `11001` | `BeforeValidate` | Before data validation |
| `11002` | `AfterSave` | After successful saving |
| `11003` | `OnClickItem` | When a menu item or button has been clicked |
| `11004` | `BeforeCancel` | Before cancelling the data sheet |
| `11005` | `OnFocusGained` | When the input focus is set to a control |
| `11006` | `OnValueChanged` | When input to a control has been completed |
| `11007` | `BeforeAddRow` | Before a row is added to a list control |
| `11008` | `BeforeDeleteRow` | Before a row is removed from a list control |
| `11009` | `AfterValidate` | After data validation |
| `11010` | `OnLeavePage` | When another page of the page control is activated |
| `11011` | `OnEnterPage` | When a page of the page control is activated |
| `11012` | `OnCellFocusGained` | When the focus is set to a cell of a table control |
| `11013` | `OnCellValueChanged` | When input to a cell of a table control has been completed |
.Hit List
| Code | Name | Description |
|---|---|---|
| `11018` | `AfterFinishQuery` | After a query has been completed |
| `11019` | `BeforeOpen` | Before a document or folder is opened |
| `11020` | `OnMove` | When an object is moved within a cabinet by drag & drop |
| `11021` | `OnAddLocation` | When an object is copied by drag & drop and a new location is added |
| `11022` | `OnCreateCopy` | When a copy of a document or register is created |
| `11023` | `BeforeDelete` | Before an object is deleted |
| `11024` | `AfterDelete` | After an object has been deleted |
.Application
| Code | Name | Description |
|---|---|---|
| `11014` | `GlobalWebClientScript` | Appended to every other web client script |
| `11015` | `GlobalWebClientObjectTypeScript` | Appended to every object type |
| `11016` | `BeforeStartQuery` | Before the actual query is executed |
| `11017` | `AfterWebClientLogin` | After the user has logged in |

### Dependency Diagram

```text
┌─────────────┐
│  event_code │
└──────┬──────┘
       │
       ├──► object_class   Numeric representation of the UI context
       │                   (redundant, directly derivable from event_code)
       │
       ├──► app_class      Target platform
       │                   1 = Client  │  2 = Server  │  3 = WebClient
       │
       └──► os_event_params   Format depends on event_code
                │
                ├── KernelBeforeJob / KernelAfterJob ──────► Job name       (e.g. "krn.EmptyJob")
                ├── JoblBeforeObject / JobAfterObject ──────► Job name       (e.g. "std.DoArchive")
                ├── OnClickItem ────────────────────────────► Field GUID     (button)
                ├── OnFocusGained / OnValueChanged ─────────► Field GUID     (input field)
                ├── OnEnterPage / OnLeavePage ──────────────► Field GUID     (page control)
                ├── JavascriptLibrary ──────────────────────► Library name   (for require())
                └── all others ─────────────────────────────► empty

┌────────────────┐
│ os_class_name  │
└───────┬────────┘
        │
        ├── "Application" ──► server-/application-wide event, no object type reference
        │
        └── "<integer>"   ──► type_id  ──►  dms.GetObjDef (asobjdef XML)
                                              └──► object type (internal name, cabinet)

┌──────────────────────────────────────┐
│  os_event_params  (if GUID format)   │
└──────────────────┬───────────────────┘
                   │
                   └──► dms.GetObjDef (asobjdef XML)
                              └──► field with matching osguid
                                    └──► label, internal name, control type
```
