Lifecycle Hooks
Scripts are bound to specific Event Types (Hooks) during the entity lifecycle. The choice of hook determines when the script runs and what actions are appropriate.
Frontend Interactivity
These hooks execute in response to UI events and block the client briefly while the server calculates the response.
OnReady: Triggered when a Form is opened. Use this to set default values, lock fields based on user roles, or display initial warnings.OnChange: Triggered when a specific field is modified (requires the field to haveTriggerPolicy: "OnBlur"in the Schema). The variableChangedFieldNametells you which property triggered the event. Ideal for real-time calculations (e.g.,Total = Qty * Price).OnUnload: Triggered when the user attempts to close or navigate away from the form. SetCancel = true;to prevent the closure if unsaved work is detected.CustomAction: Triggered by a specific Button in the UI. The variableActionNameidentifies the button.
Backend Constraints (CRUD)
These hooks run during the persistence pipeline, regardless of whether the request originated from the UI or an external API call.
OnValidate: Always runs before Create or Update. This is the designated place for data integrity checks. UseAddError("Field", "Message")to fail the validation.BeforeCreate/BeforeUpdate/BeforeDelete: Runs after validation but before EF Core saves to the database. UseBeforeCreatefor generating sequential numbers or overriding data silently. SettingCancel = true;aborts the standard database operation (useful for Virtual Entities).AfterCreate/AfterUpdate/AfterDelete: Runs after the database transaction has committed. Ideal for triggering side effects (e.g., calculating totals on a parent entity when a child line is added).
Query Interception
OnQuery: Intercepts the query before data is fetched for a Grid or List view.- WARNING: Do NOT use this for Row-Level Security (RLS) or Data Isolation. RLS must be handled natively via
Struktural_Sys_Profilerecords. - Usage: Use
OnQueryto apply complex, dynamicGridFilternodes, or to populate theEntitieslist manually if the entity is Virtual (e.g., fetching rows from a remote API).
- WARNING: Do NOT use this for Row-Level Security (RLS) or Data Isolation. RLS must be handled natively via