Wednesday, June 10, 2015

How the new Form Builder Appearance Selector Works

Recently, a customer asked us to implement a feature which looked simple at first: adding a character counter to input fields, text areas, and rich text controls (think a Tweet or an instant message which must fit in an SMS, for example). It looks like this:

Input Field with Character Counter
Input Field with Character Counter

We could have gone the easy way:

  • write 3 new custom controls,
  • add them to the Form Builder toolbox,
  • and done!

This would be easy enough to do with Orbeon Forms custom controls, but it is not an ideal solution. Instead we would like:

  • the “character counter” function to be independent from the control to which it applies (input field, text area, or rich text control),
  • and the ability to switch back and forth, in Form Builder, between a control with and one without the character counter.

Going down to the markup level (that is, how the form definition is specified), an input field looks like:

<xf:input bind="message-bind"/>

What we want to do to add the character counter is add an appearance attribute, like this:


The appearance attribute is a standard XForms attribute[1] which allows specifying how a control “looks like” without changing the kind of data it captures.

And the good news is that since Orbeon Forms 4.9 we have a mechanism to bind custom controls with an appearance. Here is how it works:

  1. We create an fr:character-counter component which implements the logic of counting the characters in a field and acts as a wrapper around an existing control,[2]

  2. and we say that fr:character-counter must apply to input fields, text areas, and other controls if desired, when the character-counter appearance is found:

    xf|input[appearance ~= character-counter],
    xf|textarea[appearance ~= character-counter]

This code specifies a “binding” for the custom control, and the cool thing is that it uses standard CSS selectors - yes, the same CSS selectors which developers use daily in their Web apps. This selector says in essence: “use this custom control implementation for input fields and text areas which have the character-counter appearance”.

But there is more: this binding is declarative which allows Form Builder to discover automatically which controls support the character counter, and propose this as an option to the form author in the Control Settings:

Character Counter Appearance Selection in Form Builder
Character Counter Appearance Selection in Form Builder

This is a fully general mechanism, which not only works for the character counter, but also for selection controls, buttons, and more:[3]

Selection Control Appearance Selection in Form Builder
Selection Control Appearance Selection in Form Builder

Under the hood, there is a not-entirely-trivial algorithm[4] which:

  1. looks at the current control’s name (such as xf:input), datatype, and appearances,
  2. checks all available control bindings in the Form Builder toolbox,
  3. and returns the list of appearances which can apply to the control given its name and datatype.

We are quite happy with the underlying architecture, and we hope the user-facing feature will be useful too! This feature will be available in Orbeon Forms 4.10.

  1. XForms specifies or suggests some standard appeararances. For example, a single selection control <xf:select1> with apperance full should show as radio buttons, while the compact appearance should show as a dropdown menu.  ↩

  2. Curious developers can see the very simple implementation of the fr:character-counter control here.  ↩

  3. We used to have a way to switch between selection controls before Orbeon Forms 4.0, but that disappeared during the big Form Builder rewrite which took place at that time. Now this feature is back but in a much more general way.  ↩

  4. Mostly implemented in BindingDescriptor.scala and BindingOps.scala.  ↩

No comments:

Post a Comment