Calculator forms: Documentation

This is a brief documentation on how to use the AllegroForms library to create interactive calculators.

You can see any of the existing calculator forms listed at the Forms homepage.

Basic notions

An interactive calculator form contains a number of "input fields" where visitors can select or type some values, and obtain computed results from the supplied values, via specified formulas or functions. The computation is performed by the browser of the visitor.

Calculator forms can be inserted in a wiki page with the "plus" button, then by selecting "Embed calculator form", and in the dialogue box, typing the form identifier, or selecting an existing one from a drop-down list.

A placeholder "Form: TheFormIdentifier" will be inserted in the page, and after the page is saved, the selected form will appear in its place.

If a form doesn't exist, the placeholder will be a link to create this form.

In the future labels for the form fields and messages could be localized, i.e. translated into different languages, with the same calculation logic.

The AllegroForms library makes it much easier to configure a form and define the computation logic, compared to writing a form in HTML, CSS, and standard (basic, plain) JavaScript.

Creating and modifying AllegroForms is restricted to trusted editors and administrators.

Form identifiers

A form identifier is a string starting with an uppercase letter, followed by uppercase and lowercase letters and/or digits.

The identifier can use capitalized words glued together, for example "SoundPressureIntensityDB" and should give an indication allowing the editors to guess the form they want to add.

Form editing

The page where a form is configured contains the following sections:

After the buttons, the same form is shown and can be used/tested.

Summary and layout

The Summary field is optional: in many cases the "form identifier" will have sufficient information. The Summary can be shown in page listings after the link to the form.

The Layout field is a drop-down where the form layout is chosen. Currently there are 2 layouts "Flow 2" and "Flow 3", which show most forms in 2 or 3 columns on a usual desktop screen.

Note that visitors may browse the wiki on mobile devices, and on narrow screens the form will "re-flow", into 2 or 1 columns.

When you create a form, try resizing your browser window to see how the form looks on narrower screens.

Result precision

This field allows to configure the precision of the results in number of decimal characters, after the calculation is completed, for all fields in the form.

For example, setting here the precision to "4" will round all results to the 4th digit after the decimal point.

Set here "0" to round the results to whole numbers.

To disable the rounding, clear the field, or set it to -1.

Individual fields can have a .=precision property that overrides the global precision for the individual field, see below.

Alternatively you can let the user select the precision, by adding a special field.

Field definitions

Here is a sample form that converts between Celsius and Fahrenheit degrees.

And here is the actual working form:

FahrenheitCelsius

A field definition looks like this:

fieldName ==initialValue >=min <=max +=step %=scale ~=formula .=precision ?=label

The field definition configures different properties of the field, as explained below.

General notions:

Field name / variable name

fieldName is the name of the field.

_fieldName is a read-only field (starts with the underscore character). Users cannot modify its value, it only shows the results of the calculations.

The following properties can be in any order.

Field types

A field type is optional; if not defined, @=number is assumed.

@=fieldType is the field type (number, checkbox, button...)

Other field types include:

@=checkbox where the user can check or uncheck a box. The value of the field is only passed to the calculation function if the field is checked. Use @=*checkbox (with an asterisk) if the field should be initially checked.

@=radio where the user can check or uncheck a radio box (one among multiple fields in a group with the same fieldName). The value of the field is only passed to the calculation function if the field is selected. Use @=*radio with an asterisk if the field should be initially selected (at most one selected from the group).

@=button A button to perform the calculation.

@=copy A button to copy all input values and results from the form, in a table which can be pasted in a text document or a spreadsheet.

@=reset A button to reset the form and restore the initial values.

@=text A text field (not a number, can show any text), single line. As with the "number" field, you can have different widths by adding a number at the end like @=text10.

@=area50x4 A multiline text area with 50 columns and 4 rows (the rows and columns are configurable). Note that the area will be limited to the available width (on the screen, or in the column).

@=date A field where the user can select a date. Its value available to the calculation function is a string in the format "YYYY-MM-DD", for example "2025-12-17". The user can type a date, or click and select one from a date picker.

@=hidden A hidden text field. It can have a name and a value, and is available to the calculation function, but nothing is shown in the page. In hidden fields you can place constants or calculated intermediate values, which can be useful to simplify inline formulas, see Calculator forms: Special fields.

@=table A table that can hold many results. This is an advanced field, see Calculator forms: Special fields.

@=html An advanced field that will be configured by a function at the form creation. This is an advanced field, see Calculator forms: Special fields.

@=config A configuration option for the library (advanced).

Values, minimum, maximum, step, precision

All the following properties are optional and can be in any order. Note that you need to use here decimal points, and not decimal commas.

==initial value
An initial value is optional; if not defined, the field will be empty.

The following apply to the default, number fields.

Number fields have arrows or +/- buttons that allow the users to increment or decrement the value with the mouse. On some browsers, users can scroll the mouse wheel to change the value. Obviously, the users can type any numeric value with their keyboard.

>=minimum value
The lowest possible value that can be entered in the field. If not set, the user can enter any value.

For example, a temperature in kelvins, or a speed of sound can set >=0 (since these cannot be negative).

<=maximum value
The highest possible value that can be entered in the field. If not set, the user can enter any value.

+=increment step
The incremental step for the value. Will be used when the user clicks on the +/- buttons.

For example, a height of a person in metres can have +=0.01 to allow a centimetre incrementation.

The user can enter any value with any precision, this only works for the +/- buttons.

The results of a calculation are not automatically rounded to this "step" value, see below how to set the precision.

Note that you need to use here a decimal point, and not a decimal comma.

.=precision
This configures how the results of the calculation will be rounded (to the number of decimal digits).

Examples, for Pi (3.141592653589793):

The field is optional. You can configure the precision globally for all fields in the form (see above), this property can override the global setting for individual fields.

Alternatively your calculation function can round the results.

Linear scale coefficient

This property usually only applies in the case of a linear conversion, but can be accessed by custom functions as well.

%=scale allows to configure a proportion between the fields, and use one of the predefined Linear conversion functions.

Note that you must use a decimal point and not a decimal comma in the scale definition. Scientific notation like 1.234E+10 is acceptable and recognized.

See the section on Linear conversion functions below.

Formula

A field ~=formula is a short way to define the calculation logic for the field, based on other fields in the form and mathematical expressions and functions.

Note that you must use a decimal point and not a decimal comma in the formula definition.

In the demonstration form above, we have these definitions (labels removed for clarity):

  Fahrenheit ~=Celsius*1.8+32 

When a user modifies the "Celsius" field, the form will immediately calculate the "Fahrenheit" field by multiplying the Celsius degrees by 1.8 and adding 32.

This is very convenient for relatively simple calculations. For more complex ones, see the "JavaScript calculation logic" section below.

See also the section on which mathematical operators and helper functions are available.

Note that formulas are calculated one after another in the order they appear in the form, so a field holding an intermediate value should be placed before fields that use that value.

Label, Prefix, Suffix, Notes, and Separators

?=A field Label is shown above the field.

A label is defined with the format ?=Text :

  Fahrenheit ?=Temperature in Fahrenheit, °F 

If a label is not defined, the "field name" will be shown. To not show any label, use a dash (minus) ?=-

^=prefix can be a very short label that is placed on the same line before the input field, which becomes shorter. If possible, do not use this property, instead write all information in the ?=label which appears above the field.

$=suffix can be a very short label that is placed on the same line after the input field, which becomes shorter. If possible, do not use this property, instead write all information in the ?=label which appears above the field.

A Note is text on a line without any field property separators ==, >=, <=, ?= and others. A note is shown full width across all columns of the form.

A Separator is a line which only contains a dash (minus "-"). It behaves like an empty Note (the minus is not displayed), spanning across the columns, so that the following fields start at the left column.

Text formatting options

Labels and notes support limited formatting via custom punctuation:

Translations

In the future, notes and labels could be translated in different languages, so that a form can be configured once and reused in all language versions. (Not yet functional.)

JavaScript calculation logic

You can have the following calculation functions:

Other families of predefined functions can be configured.

Linear Conversion

This is homogenous linear function that uses the value of the "active" field (the one typed by the user) to calculate all other fields, via their individual properties %=scale.

This is particularly appropriate to convert between different units.

These functions operate on user input or key press, no need to press on a button.

Normal linear scale

For example these 3 fields are in a fixed proportion because 1 inch is 2.54 centimetres or 25.4 millimetres:

    inch  %=1    
    cm    %=2.54 
    mm    %=25.4 

The above fields are in a "normal" scale/proportion, where "scale" "units" are the same amount for all fields: 1 inch is exactly 2.54 cm and exactly 25.4 mm.

In this case, from the function logic drop-down select "Calculation: Linear".

Inverse linear scale

Sometimes we have a list of scales that are all a factor of one specific field. For example:

    cm    %=1 
    mm    %=0.1 
    inch  %=2.54 

The above fields are in an "inverse" scale/proportion, where all "scale" numbers are in fact the number of "centimetres" in the "unit".

In this case, from the function logic drop-down select "Calculation: Linear Inverse".

Normal functions

You can launch the calculation when the user pushes a button: in this case from the function logic drop-down select "Calculation: on button click". A "Calculate" button will be added to the end of the form unless you already have a button.

You can launch the calculation while the user types: in this case from the function logic drop-down select "Calculation: on input/keypress". A "Calculate" button is not necessary and should be omitted.

The calculation can be done via formulas written in the Field definitions, or by writing some simplified JavaScript code.

Formulas

If your form fields contain formulas like:

  Fahrenheit ~=Celsius*1.8+32 

then the calculation can be done automatically, you may not need to write JavaScript code.

Note that you must use a decimal point and not a decimal comma in the formula definition.

Note that formulas are calculated one after another in the order they appear in the form, so a field holding an intermediate value should be placed before fields that use that value.

Simplified JavaScript code

You can type some custom JavaScript code in the large text area after the "Function logic" dropdown.

The text area recognizes the JavaScript syntax, will highlight the code, and will show indications in the left margin if there are errors or imprecisions.

The values from the form fields are available as local variables in your code. If your form has for example the field names Length, Width, Height, and _Volume, then in the JavaScript code you can immediately refer to these fields, for example:

  _Volume = Length*Width*Height;

This is all that you need to do for the _Volume field to be updated.

The active variable contains the field name is where the user was last typing, or the name of the button clicked by the user. For example:

  if(active == 'Length') { /*Do something with Length*/ }

When the local variables are modified by your code, the corresponding fields in the form will be updated.

Note that you must use a decimal point and not a decimal comma in the JavaScript code.

Note that if you define a ~=formula in the field, its local variable fieldName will already have been recalculated with the formula. To get the pre-formula value, use $.fieldName.

While the AllegroForm library greatly simplifies writing calculation logic, some knowledge and experience with JavaScript will be really useful to editors.

If you have any questions or difficulties, please do let us know.

Operators in JavaScript

Mathematical calculation in JavaScript uses the normal rules for priority of operators and parentheses:

  1. Parentheses (...)
  2. Exponentiation x**y (right to left, see below)
  3. Multiplication x*y and Division x/y (left to right)
  4. Addition x+y and Subtraction x-y (left to right)

The Exponentiation ** operator has the following particularities:

Available constants and helper functions

Constants

E
Euler's constant and the base of natural logarithms; approximately 2.718.
LN2
Natural logarithm of 2; approximately 0.693.
LN10
Natural logarithm of 10; approximately 2.303.
LOG2E
Base-2 logarithm of E; approximately 1.443.
LOG10E
Base-10 logarithm of E; approximately 0.434.
PI
Ratio of a circle's circumference to its diameter; approximately 3.14159.
SQRT1_2
Square root of 1/2; approximately 0.707.
SQRT2
Square root of 2; approximately 1.414.
K_BOLTZ
The Boltzmann constant, 1.380649×10-23 J/K

We can add other constants (Maths or Physics) as needed.

Mathematical helper functions (note that all trigonometry functions accept or return radians, not degrees):

abs(x)
Returns the absolute value of x.
acos(x)
Returns the arccosine of x.
acosh(x)
Returns the hyperbolic arccosine of x.
asin(x)
Returns the arcsine of x.
asinh(x)
Returns the hyperbolic arcsine of a number.
atan(x)
Returns the arctangent of x.
atanh(x)
Returns the hyperbolic arctangent of x.
atan2(x)
Returns the arctangent of the quotient of its arguments.
cbrt(x)
Returns the cube root of x.
ceil(x)
Returns the smallest integer greater than or equal to x. Note that for negative numbers it also rounds the value up.
cos(x)
Returns the cosine of x.
cosh(x)
Returns the hyperbolic cosine of x.
exp(x)
Returns the ex, where x is the argument, and e is Euler's constant (2.718…, the base of the natural logarithm).
expm1(x)
Returns subtracting 1 from exp(x).
floor(x)
Returns the largest integer less than or equal to x.
hypot(a, b, c...)
Returns the square root of the sum of squares of its arguments.
log(x) or ln(x)
Returns the natural logarithm (㏒e; also, ㏑) of x. Note that base-10 logarithm is log10(x)
log1p(x)
Returns the natural logarithm (㏒e; also ㏑) of 1 + x for the number x.
log10(x)
Returns the base-10 logarithm of x.
log2(x)
Returns the base-2 logarithm of x.
max(a, b, c...)
Returns the largest of zero or more numbers.
min(a, b, c...)
Returns the smallest of zero or more numbers.
pow(x, y)
Returns x to the exponent power y (that is, xy). Alternatively you can use the exponentiation operator x**y.
pow10(x)
Returns 10 to the exponent power x (that is, 10x). Alternatively you can use the exponentiation operator 10**x.
random()
Returns a pseudo-random number between 0 and 1.
root(x, n)
Returns the n-th root of x; if called without a second argument, returns the square root of x.
round(x)
Returns the value of the number x rounded to the nearest integer.
rnd(x, n)
Returns the value of the number x rounded to n decimal digits.
sign(x)
Returns 1, -1, or 0 if x is positive, negative, or zero.
sin(x)
Returns the sine of x.
sinh(x)
Returns the hyperbolic sine of x.
sqrt(x)
Returns the positive square root of x.
tan(x)
Returns the tangent of x.
tanh(x)
Returns the hyperbolic tangent of x.
trunc(x)
Returns the integer portion of x, removing any fractional digits.

Other helper Maths functions:

isN(a, b, c...)
Returns true if all arguments are numeric, and not of the 'NaN' variant, but may include Infinity.
cntN(a, b, c...)
Returns the number of numbers among the arguments. You can use this to easily check how many fields are filled.
isFinite(x)
Returns true if x is a finite number.
isNaN(x)
Returns true if x is not a number. If x is a numeric string like "4.2", this returns false, but you need to use parseFloat(x) before using it in calculations.
parseFloat(x)
Tries to convert x to a floating point number. If successful, returns the number, otherwise a special element 'NaN' ("not a number").
floatval(x)
Returns the string parsed to a floating point number, or zero if the string cannot be parsed as a number.
intval(x)
Returns the string parsed to an integer, or zero if the string cannot be parsed as a number.
deg2rad(degrees)
Converts degrees to radians.
rad2deg(radians)
Converts radians to degrees.
x.toFixed(n)
Returns x rounded to n decimal places, with trailing zeros. For example, 4.toFixed(2) will return the string '4.00'. The result is a "string" and can no longer be used for reliable calculations, but can be useful to print the final results.
percent(x, n)
Converts x to percent, rounded to n decimal places, with trailing zeros kept, and with added '%' symbol. Basically returns (x*100).toFixed(n) + '%'.

Other helper Physics functions:

toKelvin(x, scale)
Returns x in kelvin. The argument scale can be "K" (kelvin), "C" (Celsius), "F" (Fahrenheit) or "R" (Rankine). If the result is below the absolute zero, returns zero.

We can add other helper Physics functions as needed.

Input and output and variables. The variables below are local and available for your JavaScript logic, not global variables.

active
The "name" of the active field (the one where the user types, or the button that was pushed).
$
A read-only object with all input values (same as the local variables). For example, a field name Length will be available both as a local variable Length and as an element from the object $.Length.
$$
An object with all output values (results). You can either modify a local variable, or the $$ object to update the fields of the form. For example, to update a field "Length" to the value 3, either set Length = 3; or $$.Length = 3;. If you define values in the $$ object, they will not be overwritten by the local variables.
orig_fieldName and $.orig_fieldName
This is the original "string" value of the field "fieldName" as available in the form, before its conversion to a floating point number (fieldName or $.fieldName). Can be used if an automatic conversion is not desirable. Note that the output values still need to use the field name, without the prefix "orig_".
MESSAGE = "message";
Use this to show a message to the user. The message appears above the form, and has a button "OK" to close it.
return halt("message");
Use this to immediately stop the processing and show a message to the user.
echo(active, $, myFieldName...); or console.log(...);
This will show information about the variables / arguments in the JS console in the browser -- press F12 to open the console. You can use this to check intermediate values in your processing logic.