On this blog, we often mention new features we recently implemented in Orbeon Forms, but rarely discuss how they have been implemented. Today, let’s make an exception, and come back to a feature discussed a couple of weeks ago: Form Builder’s new UI to edit labels and hints.
UI programming often consists in doing something in reaction to some event (
event → action). For instance: in Form Builder, when the mouse pointer enters a cell, show the icons to edit the control in that cell. Sometimes, you only want to take the action if a condition is met (
event, if condition → action). Yet, in other cases, the action to be performed depends on a state, for instance: if form authors click somewhere on the page, and the label is in the edit state, switch it to read-only mode. Putting all this together, for the case of editing the labels and hints, you get the situation in this diagram:
Now, that is hairy, isn’t it? (And this diagram only shows states, events, and conditions, but not the actions to be performed.) Having this logic spread throughout your code makes things hard to maintain (read: impossible to maintain!). Luckily, the concept of finite state machine (FSM) comes to the rescue. A FSM allows us to break our code into the following parts:
- A description of the transitions shown in the above diagram, what conditions need to be met for a transition to happen, from which and to which state it goes, and what actions need to run when that transition is made.
- The implementation of the events, conditions, and actions referred to in #1.
- A generic FSM “engine”, which take the transitions, events, conditions, and actions from #1 and #2 and runs them.
Last month, we develped a new FSM engine and used it to implement Form Builder’s new UI to edit labels and hints, and since then, we already started using that engine to implement other Form Builder features.