Feature: Make buttons perform actions with action formulas

Action formulas make things happen, unlike regular functions, which calculate values. They are our biggest new feature yet. Use them to model complex business logic.

Action formulas are the biggest addition to Calcapp yet. Unlike regular formulas, which calculate values, action formulas make things happen.

These are some of the things an action formula can do:

  • Send a report, but only if the entered data is valid. Otherwise, show the user an alert box.
  • Ask the user a series of questions, before sending a report incorporating the entered answers.
  • Send multiple reports, incorporating different information, to different email addresses.
  • Open a report on the user’s device, while also sending a message to the team’s internal Slack channel. (Integration with Slack, and other third-party services like Google Sheets, Excel and Salesforce require a third-party service like Zapier.)
  • Reset all fields, but only if the user first consents by pressing a button to that effect in a message box. Then, move the user back to the first screen, and ensure that previously-hidden text boxes are once more visible.

To support action formulas, we have introduced 30 new action functions, which can do everything that a regular button can do, and more. Action formulas also support the := operator, which assigns values to properties. They can only be used from action formulas.

This action formula asks the user for their name and greets them once the name has been entered:

AWAIT(PROMPT("What's your name?"), BANNER("Hi " & Result & "!"))AWAIT(PROMPT("What's your name?"); BANNER("Hi " & Result & "!"))

Action formulas 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.

These formulas can only be attached to the OnPress property of formula buttons. We will consider enabling action formulas elsewhere in the future.

Action formulas are not available in any of our legacy plans, meaning that you may need to upgrade to access them. They are available in our 2023 White Label plans. Action formulas are fully functional in Calcapp Creator’s preview sidebar, though, so you can get a feel for them, regardless of your plan.

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.

Fields is a new property. Learn more about it here.

Running multiple actions

An action formula can perform 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.

Closing words

Formula buttons can also be used to realize the oft-requested calculation buttons, that only perform calculations once the user presses a button. The key addition that makes this possible is the new := operator, which assigns values to properties. Learn more about calculation buttons.

New functions like PROMPT may be used to query users for information. Learn more about asking users questions.

Finally, action formulas are the culmination of a multi-year effort. Five and a half years ago, we publicly mused about what they might look like.

We think that the action formulas we present today are far stronger than that early proposal. This is mostly thanks to our new formula engine, which was built from the ground up to support action formulas. Now that action formulas are a reality, it is finally complete.

« Feature: An editor for tabular data Feature: Eleven new button types »