Manual · API
form & event
Inside a form script, form is this window — its objects by name, its record — and event says what just happened. Both exist only where they mean something: a menu script has no form.
Timings are measured, never guessed — a 7,500-invoice database on an Apple-silicon Mac, warm, median of many runs (Spikes/CommandTimingSpike). green never needs a thought · amber is felt in a loop · red takes real time, show progress.
Every command on this page carries a worked example.
form.record property
form.record no traffic — the bound record is already in hand
The record this window is bound to. What you type is already in it — a script reading form.record.name sees the screen's truth.
Worked example
// The screen's truth, mid-typing:
form.header.value = form.record.name || "New customer";
form.<object> property
form.header · form.list · form.nameField show(query) runs the query on the server a 50-row list ≈ 2 ms
Every object of the form, by its name. Labels have value, lists have show(), value (the chosen record) and reload(), wells have their file.
Worked example
// A list obeys a script: show a search result instead of its table.
const found = database.products.where("stock", "<", 10);
form.list.show(found);
form.countLabel.value = found.count() + " below minimum";
form.close function
form.close(result) no traffic — a local window act
This window closes, handing result to whoever opened it modally — the relationship database has to record.
Worked example
// A small modal form answers its opener:
form.close(form.record.discount); // the opener's forms.open(...) returns this
form.load function
form.load(record) one record is fetched ≈ 0.15 ms
Points the open window at another record — how one window browses a set instead of opening a window per record.
Worked example
// A Next button that browses without opening windows:
const next = database.invoices
.where("date", ">", form.record.date)
.orderBy("date").first();
if (next !== null) { form.load(next); }
form.variable property
form.variable.<name>
What this window remembers while it is open — the middle of the three scopes a value can live in (a script's own let, this window, this session's application.variable). Two windows of one form remember two different things, and closing a window forgets its own. Declare the names in the form's inspector under Variables and the editor completes them, checks them and renames them; an undeclared name still works.
form.variable = {} forgets the lot.Worked example
// searchField.onChanged — put it down where the next event can find it
form.variable.searched = form.searchField.value;
// buttonFind.onClick — a different event, the same window
const found = database.invoices
.where("number", "contains", form.variable.searched);
form.list.show(found);
event property
event.column · event.record · event.previous …
What just happened, for the event being handled: the edited column and its previous value in onCellChanged, the failing message in onError, the row in list events.
Worked example
// tables/invoices/onValidate.js — the rule EVERY writer obeys:
// the form, the import, the data browser and every script.
if (event.column === "discount" && event.value > 50) {
event.refuse("More than 50 % needs a manager.");
}
Manual