OnPress property

FormulaButton.OnPress

Special value available in formulas:

Item

FormulaButton

The button this property is part of, enabling multiple checked items in the app designer to share the same formula and be updated all at once.

Consider the fields Field1 and Field2, which should only be considered to be valid if their values are greater than 4. Without using the Item value, the Valid property of Field1 would need to use the formula Field1 > 4Field1 > 4 and the Valid property of Field2 would need to use the formula Field2 > 4Field2 > 4.

Using Item, both formulas can read Item > 4Item > 4. This is useful if you have many fields and you want to be able to update their formulas all at once. To do so, click their check boxes in Calcapp Creator and make sure that a checked field is selected. Then, when you update a formula for one checked field, you update all the other checked fields too, which is a great timesaver.

Use Item in exactly the same way you'd use the regular name. Button1.VisibleButton1,Visible and Item.VisibleItem,Visible are equivalent, for instance.

Invoked when the user presses the button.

Only action formulas may be associated with this property. Unlike a regular formula, which calculates a value, an action formula makes something happen. It does so by assigning a value to another property using := or by invoking an action function.

(Of course, regular functions may be used to calculate the value to assign to a property with :=, and to calculate the parameters given to action functions.)

An action function can do everything that a regular button can, including sending email, copying values to the clipboard, displaying a different screen and showing messages. Action formulas also have access to functions not accessible to regular buttons, which enable you to ask users to enter text or numbers, show transient banners and ask users for confirmation.

Unlike regular buttons, a formula button can perform multiple actions, either one after another, or by waiting for one to complete before invoking the next one. Action formulas can also use conditional logic, meaning that an action is only performed if one condition is TRUE, otherwise another action is performed. This makes it possible to model complex business logic.

This action formula shows a message:

ALERT("Hello, world!")ALERT("Hello, world!")

This action formula assigns a value to Field1:

Field1 := 42Field1 := 42

This action formula hides a text box:

TextBox1.Visible := FALSETextBox1,Visible := FALSE

Here is the full list of action functions.

Using IF to express conditions

Use a function like IF or SWITCH to perform one action if a condition evaluates to TRUE and another action otherwise.

This formula sends an email if all fields in the app are valid and shows a message otherwise:

IF(AND(App.Fields.Valid), EMAILREPORT({ App }, "test@example.com"), ALERT("Please correct the fields first."))IF(AND(App,Fields,Valid); EMAILREPORT({ App }; "test@example.com"); ALERT("Please correct the fields first."))

App.Fields.ValidApp,Fields,Valid returns a logical array, where TRUE indicates that a corresponding field is valid and FALSE indicates that a corresponding field is invalid. AND returns TRUE only if all those elements are TRUE, meaning that all fields are valid.

Running multiple actions

A button can run any number of actions. Separate actions with ;;;.

This action formula assigns two values to two different fields and hides a text box:

Field1 := SUM(FormGroup1); Field2 := Field1 * 10; TextBox1.Visible := FALSEField1 := SUM(FormGroup1);; Field2 := Field1 * 10;; TextBox1,Visible := FALSE

By chaining together multiple actions with ;;;, you can create buttons that do nothing but calculate values. For some apps, this can be an appealing alternative to having Calcapp calculate values as the user types.

This formula resets all fields of the app and then brings the user back to the first screen:

RESET(App); GOBACK(FirstScreen)RESET(App);; GOBACK(FirstScreen)

This formula assigns values to the fields of a screen named SecondScreen, before taking users to it:

SecondScreen!Result1 := FirstScreen!Field1 * 2; SecondScreen!Result2 := FirstScreen!Field2 * FirstScreen!Field1; GOFORWARD(SecondScreen)SecondScreen!Result1 := FirstScreen!Field1 * 2;; SecondScreen!Result2 := FirstScreen!Field2 * FirstScreen!Field1;; GOFORWARD(SecondScreen)

If users should only be able to reach the second screen through the button, and not by pressing Next in the upper-right corner, ensure that the NextScreenAvailable property of whatever screen precedes it is set to FALSE.

Waiting for actions to complete

Many action functions perform actions that can take some time to complete. EMAILREPORT, for instance, sends a report through email. It does so by asking our server to create the report and send it, which takes a second or two.

EMAILREPORT lets you perform other actions while our server is busy fulfilling the request. This action formula asks our server to start the process, and then immediately shows a banner:

EMAILREPORT({ App }, "test@example.com"); BANNER("Sending the report, hold tight!")EMAILREPORT({ App }; "test@example.com");; BANNER("Sending the report, hold tight!")

If you want to perform an action once the report has been successfully sent, use the AWAIT function. This formula shows another banner when the report has been sent:

AWAIT(EMAILREPORT({ App }, "test@example.com"), BANNER("All done!")); BANNER("Sending the report, hold tight!")AWAIT(EMAILREPORT({ App }; "test@example.com"); BANNER("All done!"));; BANNER("Sending the report, hold tight!")

Handling errors

The AWAIT function takes three parameters: the action, the formula fragment which is run when the action completes successfully and the formula fragment which is run if there is a problem completing the action. Only one of the latter two parameters must be provided, meaning that you can write a formula that only takes action if a completing the first action fails.

This formula shows an error message if sending a report fails:

AWAIT(EMAILREPORT({ App }, "test@example.com"), OnFailure: ALERT("Could not send report: " & Error.Message))AWAIT(EMAILREPORT({ App }; "test@example.com"); OnFailure: ALERT("Could not send report: " & Error,Message))

Above, the third parameter, OnFailure, is given a name. That enables us to completely leave out the second parameter, which we don't need. An alternative to naming the third parameter is to use BLANK()BLANK() as the value for the second parameter:

AWAIT(EMAILREPORT({ App }, "test@example.com"), BLANK(), ALERT("Could not send report: " & Error.Message))AWAIT(EMAILREPORT({ App }; "test@example.com"); BLANK(); ALERT("Could not send report: " & Error,Message))

The third parameter has access to a special value, named Error, which has more information on the error, including an error message.

If an action function does not complete successfully, and you don't handle the error by providing an OnFailure parameter, your app will show an error message. If you don't want your users to see any error messages, not even your own, you can pass BLANK()BLANK() as the OnFailure parameter.

Asking users questions

Use the PROMPT and PROMPT.NUMBER functions to ask users to enter text strings or numbers, respectively. Use AWAIT to read the entered value.

This formula asks the user to enter the email address where a report should be sent, before sending the report:

AWAIT(PROMPT("Enter email address:"), EMAILREPORT({ App }, Result))AWAIT(PROMPT("Enter email address:"); EMAILREPORT({ App }; Result))

The second parameter to AWAIT has access to a special value named Result, containing the result communicated by the action. For PROMPT the result is the text string entered by the user. For PROMPT.NUMBER, the result is the number entered by the user.

(This is similar to the third parameter to AWAIT, which has access to a special value named Error, with additional information on what went wrong.)

If you like, you can use -> to rename the Result value:

AWAIT(PROMPT("Enter email address:"), EmailAddress -> EMAILREPORT({ App }, EmailAddress))AWAIT(PROMPT("Enter email address:"); EmailAddress -> EMAILREPORT({ App }; EmailAddress))

You can ask the user any number of questions:

AWAIT(PROMPT("First value:"), Value1 -> AWAIT(PROMPT("Second value:"), Value2 -> ALERT("First value: " & Value1 & ", second value: " & Value2 & ".")))AWAIT(PROMPT("First value:"); Value1 -> AWAIT(PROMPT("Second value:"); Value2 -> ALERT("First value: " & Value1 & ", second value: " & Value2 & ".")))

When asking multiple questions with PROMPT, it is necessary to rename the Result value. If we don't, there is no way to access results other than the last one.

Finally, use CONFIRM to ask users to confirm a choice. This formula asks the user to confirm before resetting all fields of the app, immediately followed by displaying the first screen:

AWAIT(CONFIRM("Reset all?"), RESET(App); GOBACK(FirstScreen))AWAIT(CONFIRM("Reset all?"); RESET(App);; GOBACK(FirstScreen))

Examples

ALERT("Hello, world!")ALERT("Hello, world!")

Displays an alert with the message "Hello, world!".

Field1 := 42Field1 := 42

Assigns 42 to the value of Field1.

Field1.Value := 42Field1,Value := 42

Assigns 42 to the value of Field1. If .Value,Value is left out, it is inferred.

TextBox1.Visible := FALSETextBox1,Visible := FALSE

Hides TextBox1.

IF(Field2 < 4, Field1 := Field2, Field1 := BLANK())IF(Field2 < 4; Field1 := Field2; Field1 := BLANK())

Sets the value of Field1 to the value of Field2, but only if the value of Field2 is less than 4. Otherwise, the value of Field1 is set to a blank value.

Field1 := IF(Field2 < 4, Field2, BLANK())Field1 := IF(Field2 < 4; Field2; BLANK())

Sets the value of Field1 to the value of Field2, but only if the value of Field2 is less than 4. Otherwise, the value of Field1 is set to a blank value. The previous formula uses IF to determine what action to take, but IF can also be used to return a regular value, which is then assigned to Field1.

IF(AND(App.Fields.Valid), EMAILREPORT({ App }, "test@example.com"), ALERT("Invalid fields."))IF(AND(App,Fields,Valid); EMAILREPORT({ App }; "test@example.com"); ALERT("Invalid fields."))

Sends an email if all fields in the app are valid and shows a message otherwise.

Field1 := 10; Field2 := 20Field1 := 10;; Field2 := 20

Assigns 10 to Field1.ValueField1,Value and 20 to Field2.ValueField2,Value. Use ;;; to separate actions.

RESET({ App }); GOBACK(FirstScreen)RESET({ App });; GOBACK(FirstScreen)

Resets all fields of the app and brings the user back to FirstScreen.

SecondScreen!Result1 := 42; GOFORWARD(SecondScreen)SecondScreen!Result1 := 42;; GOFORWARD(SecondScreen)

Assigns 42 to the value of Result1, residing on the screen SecondScreen. The user is then brought forward to that screen.

EMAILREPORT({ App }, "test@example.com"); BANNER("Sending the report")EMAILREPORT({ App }; "test@example.com");; BANNER("Sending the report")

Sends a report and immediately shows a banner.

AWAIT(EMAILREPORT({ App }, "test@example.com"), BANNER("Done!"); BANNER("Sending the report"))AWAIT(EMAILREPORT({ App }; "test@example.com"); BANNER("Done!");; BANNER("Sending the report"))

Sends a report and immediately shows a banner. When the report has been sent, another banner is shown.

AWAIT(EMAILREPORT({ App }, "test@example.com"), OnFailure: ALERT("Failed: " & Error.Message))AWAIT(EMAILREPORT({ App }; "test@example.com"); OnFailure: ALERT("Failed: " & Error,Message))

Sends a report and displays an alert, with an error message, if sending the report fails.

AWAIT(PROMPT("Enter email address:"), EMAILREPORT({ App }, Result))AWAIT(PROMPT("Enter email address:"); EMAILREPORT({ App }; Result))

Asks the user to enter their email address before sending a report to that very address.

AWAIT(PROMPT("First value:"), Value1 -> AWAIT(PROMPT("Second value:"), Value2 -> ALERT("First value: " & Value1 & ", second value: " & Value2 & ".")))AWAIT(PROMPT("First value:"); Value1 -> AWAIT(PROMPT("Second value:"); Value2 -> ALERT("First value: " & Value1 & ", second value: " & Value2 & ".")))

Asks the user to enter two values before displaying them. -> is used to rename the returned values entered by the user, which is necessary in order to tell them apart. (The name Result would otherwise have been used for both values.)

AWAIT(CONFIRM("Reset all?"), RESET({ App }))AWAIT(CONFIRM("Reset all?"); RESET({ App }))

Asks the user for confirmation before resetting all fields.