Skip to content

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) and hideRowById(id) — one control.
  • showRowsById([...]) and hideRowsById([...]) — 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.
  • Controls — the controls the script manipulates.
  • Conditions — the declarative alternative to scripting.
  • Triggers — where server-side logic belongs.