# Button creation

Release: 4.6  •  5.0  •  5.1  •  5.2  •  5.3  •  5.4  •  6.0  •  6.1  •  6.2  •  6.3

A button is a special kind of user interface object you can add to a diagram. It contains an expression that is executed when you press the button (in browse mode, or with Alt+click in edit mode).

To make a button: To create a new button, enter edit mode, and drag from the button icon at the right end of the new object toolbar onto the diagram (or press Control+0).

OnClick attribute: The OnClick attribute holds an expression that gets evaluated when the button is pressed. You can view and edit the expression in the Attribute panel as above, or its Object window, like any user-editable attribute. The expression uses the same syntax as a Definition, but unlike a variable Definition, it allows side-effects such as assignment to global variables or object attributes. Also unlike a variable Definition, the result value is not stored or used. From the expression, you can call any of the functions that are available in Analytica. If variables are later renamed, the expression is automatically updated.

Note: In earlier releases of Analytica, the Script attribute held the commands executed when the button is pressed. The Script attribute can still be used (it is run after OnClick), and legacy models continue to work, but it has been superseded by the OnClick attribute. Script uses a different syntax called typescript. With the introduction of OnClick, there is no longer a need to learn another syntax since OnClick uses the same expression syntax as Definition.

## Assigning to global variables

Assigning a definition in OnClick or OnChange: A statement in a button or change event can assign to a nonlocal (global) variable, for example:

A := 100

This is not permitted in the definition of a variable, which only assigns to local variables declared within the definition of the variable, to prevent side effects — where evaluating one variable changes the value of another. See Assigning to a local value: v := e.

If the variable being assigned to has an Onchange attribute set, the OnChange event evaluates after the assignment is made, unless the OnChange event is already running.

The right-hand side of the expression is evaluated before the assignment. Hence, an assignment of

A := B + 1

evaluates B, adds 1, and sets the Definition of A to the result.

## Assigning a value in a function

There is an important exception to the rule that you cannot assign to globals in a definition: You can assign to a global variable in a function that is called from a button event. It can be called directly or indirectly — that is, called from a function called from an OnClick, OnChange or Script attribute, and so on recursively:

Variable A := 100
Variable B := 2
Function IncrementA
Parameters: (x)
Definition: A := A + x
Button Add_B_to_A
OnClick: IncrementA(B)

When you press button Add_B_to_A, it calls function IncrementA, which sets the definition of A to the current value of A + B, i.e., 102. Like any assignment in a function, it assigns the value not the expression A + B.

This kind of global assignment gives you the ability to create buttons and functions to make changes to a model, including such things as modifying existing model values and dependencies.

## Save a computed value

One useful application of assigning to a global variable is to save the results of a long computation. Normally, the cached result of a computation is stored until you change any ancestor feeding into the computation, or until you Quit the session. By assigning the result to a global variable, you can save it so that it remains the same when you change an input, or even when you quit and later restart the model.

A common case where this is helpful is a model containing two parts: (1) A time-consuming statistical estimation, neural network, or optimization that learns a parameter set, and (2) a model that applies the learned parameters to classify new instances. After computing the parameters, you can save them into a set of global variables, and then save and close the model. When you restart the model, you can apply the learned parameters to many instances without having to waste time recomputing them.

Consider this example:

Variable Saved_A := 0
Button Save_A
OnClick: Saved_A := A

When you click button Save_A, it saves the value of A into global Saved_A. Saved_A retains this value if you change A or any of its predecessors, or even if you quit the session, saving the model file, and later restart the model. Thus, you won’t have to wait to recompute Saved_A. Of course, the value of Saved_A does not update automatically if you change any of its predecessors, the way A does. You need to click button Save_A again to save a new value of A.

If the value of A is an array with nonlocal indexes, the definition of Saved_A is an edit table, using those indexes. Any subsequent change to those indexes affect, and possibly invalidate the table. If you want to make sure this doesn’t happen, you might want to save copies of the indexes, and transform the table to use the saved indexes.

## Assign to an attribute

You can assign to any user-editable attribute of a (nonlocal) variable or other object, subject to the same restrictions as assigning a value — i.e., you can do it only in a function called from OnClick or OnChange, directly or indirectly. You cannot assign to an attribute in the definition of a variable. The syntax is:

<attrib> OF <object> := <text>

Here <attrib> is the name of an editable attribute, including Title, Units, Description, Definition, Check, Domain, and Author; <object> is the identifier of a user-defined, nonlocal object, variable, function, module, etc.; and <text> is a text value. For example:

Variable Gray := 0
Title: Gray
Button Change_title
OnClick: Title of Gray := 'Earl '& (Title of Gray)

When you click button Change_title, it calls function Retitle applying it to variable Gray, prefixing the old title of Gray with Earl to become Earl Gray. It does this again each time you press the button.

If the text is an array, it flattens the array into a single text value before the assignment — probably not what you want. So, it is best only to assign atomic text values.

If you want to assign a new definition as text (rather than assigning the value of an expression), you can assign to the definition thus:

Definition OF X := 'Y^2

You can use this method to assign new values to various internal attributes, such as NodeLocation, NodeColor, NodeSize, and NodeFont, letting you change the way nodes appear on a diagram. Consult the Analytica Wiki for more details on attributes.

## Invalidate a result

When a variable pulls data from an external source, or when a variable makes use of random numbers, invalidating a previously computed result for that variable forces the data to be refreshed the next time it is accessed. To invalidate the result of variable Y, use:

InvalidateResult(Y)