Meet UFX: Umbraco Forms Expressions

TLDR; A demonstration

The problem

Recently we've been creating quite a few forms with Umbraco to support inbound strategies for our customers. They basically let the user input different financial or measurable values. When the form is posted, we do some calculations to provide the user with some useful feedback. We also check the value and decide whether the user is a useful lead to put into the CRM, or whether she should be offered a subscription to the newsletter instead.

For each of the calcluations, a developer has to hack up a new workflow type for Umbraco Forms. This means that for even the simplest calculations, we need the dev. team to schedule time for the customer. Wouldn't it be great if the business people themselves could do these calculations?

Enter UFX

A few years ago I was introduced to Irony. Irony is a language toolkit for the .net platform. With it we can build our own language grammars and according abstract syntax trees. Sadly, I couldn't invest much in it at the time, so it was left on the shelf for a while. I picked it up on my way to the Umbraco UK Festival, and fell in love again. So I started creating a package aptly called "Umbraco Forms Expression", UFX for short. I'd blog about building this package, but I hardly understand what I'm doing myself. In any case, it's a small language for doing calculations on Umbraco Forms record values. It can be used to set field values based on calculations on other field values.

Let me take you through a loan calculator example where we calculate the total amount and monthly payment based on interest and terms. I hardly know my way around those formulas either, but if you're interested, this page holds a lot of good information.

Building the loan calculator

I started by building this simple form in Umbraco. It has text fields for amount, interest and terms, all validated as numbers (with decimals). There's also hidden fields for the total and monthly payment results:

I took the liberty of allowing text pages below text pages in Fanoe, so I could add a result page with a macro. The macro just points to a partial view. In the partial view, I load up the record and show the interesting fields:

When the user visits the calculator, she'll fill out the amount, interest and terms.
Sending the form yields the very little interesting repetition of the amount:

Granted, we could've put the calculation in the results, but then we couldn't have re-used workflows that push the record values to a CRM for instance.

Using UFX

To add the calculation without coding, we add the new UFX Expression workflow to the form:

It opens with one setting: the program. You can enter a formula directly in the Ace editor here if you feel confident.

For complex expressions though, a workbench is needed. Clicking the small fullscreenish button just above the program box opens a full view of the program, and lets you test the expression using different values.
When entering a program into the editor, textboxes appear on the right hand side for each field you use in the expression. Fields are referenced using square brackets as such: [loan amount].

Clicking the run button in the bottom right runs the calculation on the server and displays updated fields and their values. Notice you can add as many variables you'd like.

And that's it, really. Saving the form with this workflow makes it so the calculation is done as part of the workflow evaluation. Adding workflows after it lets you put the loan total and montly fee in external systems, as well as reference them in e-mails to the user or administrator.

Here's a shot of the result page with the workflow in place:

Current limitations

First of all, this is open source! I'll gladly welcome help making the UI more polished for starters. My ambitions for the language is to keep it dead simple, so don't expect me to pull a full C# implementation.

For now it only does math on numeric field values. There's a few math functions included. I'll include more when they're needed. It's all documented in the wiki on the github site.

I'll leave the package in beta, hoping for some good feedback. Reach out to me on twitter, or add some feedback on the issue tracker. Looking forward to hearing from you! :)

Next steps

There's obvious next steps for this. Boolean values for one. Conditionals on numbers, bools or even strings can well be introduced. It's all fairly easy since Irony comes with a lot of basic language constructs to re-use.

A worflow setting letting you execute the workflow based on a program returning a boolean can also be spotted on the horizon if you squint.

Incidentally, I've also got another idea codenamed UQL I might pick up in the mean time. I'll let you guess what it'll do for now. It might surface within a few weeks.

Again, I'd like to take this slow, keep it simple and evolve based on real needs. Keep the feedback coming, and do pitch in if you find this kind of thing interesting.