Form scripting¶
Forms accept JavaScript: the javascript control holds code that runs in the browser with the form. This page lists what that code can reach.
Finding a control¶
| Function | Finds a control by |
|---|---|
getFieldById(id) |
The id attribute |
getFieldByName(name) |
The control's name |
getFieldByVariable(variable) |
The case variable it is bound to |
getFieldByAttribute(attribute, value) |
Any attribute |
getFormById(id) |
The form itself |
getSubformById(id) |
A subform |
getFieldByVariable is the one to use when the code must survive a rename of the
control: the variable is the stable part.
A field object exposes a value property, and a checkbox exposes checked.
Reading and writing a value¶
var price = getFieldByName("price").getValue();
getFieldByName("total").setValue(price * 1.16);
getValue() returns what the control holds: text for a field, an array for a
checkgroup, and the rows for a grid. setValue() writes the value back into the form;
the case only stores it when the form is submitted.
Working with a grid¶
A grid takes a row and a column in both directions:
var grid = getFieldByName("items");
grid.addRow({}); // a new empty row
grid.setValue(10, 0, "price"); // row 0, column "price"
var total = grid.getValue(0, "price");
grid.removeRow(0);
The row index is the position in the grid, starting at 0. Removing a row shifts the
rest, so remove from the last row backwards when clearing several.
Reacting to what the user does¶
leimnud.event.add(getFieldByName('country'), 'change', function () {
// runs when the country changes
});
The event you need depends on the control:
| Control | Event that fires when the value changes |
|---|---|
| text, textarea, currency, percentage | blur — when the user leaves the field |
| checkbox | click |
| dropdown, radiogroup, listbox, date | change |
A blur does not fire while the user is still typing, which is the usual reason a
calculation "does not update" until the user clicks elsewhere.
Showing and hiding¶
The conditional show/hide rules use these helpers, and your own code can call them:
showRowById(id)andhideRowById(id)— one control.showRowsById([...])andhideRowsById([...])— several at once.
Hiding a control does not clear its value: it is hidden, not deleted.
External files¶
Code that several forms share can live in a public file of the process and be included from the form. That keeps one copy of the logic instead of one per form.
A worked example¶
A form with quantity, price and total, where the total follows the other two:
function recalculate() {
var quantity = parseFloat(getFieldByName("quantity").getValue()) || 0;
var price = parseFloat(getFieldByName("price").getValue()) || 0;
getFieldByName("total").setValue((quantity * price).toFixed(2));
}
leimnud.event.add(getFieldByName("quantity"), "blur", recalculate);
leimnud.event.add(getFieldByName("price"), "blur", recalculate);
parseFloat with a fallback of 0 handles the empty field: without it the result is
NaN, which is what a "broken" calculation usually is.
Debugging¶
The browser console is the only place the script reports. To see what a control holds:
console.log("total", getFieldByName("total").getValue());
If nothing appears, the selector did not find the control — check the control's name,
not its label. A script that fails silently usually threw before reaching the
console.log, so look for the first red line in the console, not the last.
Rules that matter¶
- The code runs in the browser, so a user can skip it. Anything that must be enforced is checked again in a trigger.
- An error in the script stops the rest of the script; the form still works, but the behaviour you expected does not happen.
- The script sees the form, not the server: it cannot query the database directly. Use a control with a database connection, or a trigger.
- Debugging is the browser's console, not the case debug view. That view shows the server side.
Related¶
- Controls — the controls the script manipulates.
- Conditions — the declarative alternative to scripting.
- Triggers — where server-side logic belongs.