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:

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:
<xf:input
bind="message-bind"
appearance="character-counter"/>
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:
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]and we say that
fr:character-counter
must apply to input fields, text areas, and other controls if desired, when thecharacter-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:

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

Under the hood, there is a not-entirely-trivial algorithm[4] which:
- looks at the current control’s name (such as
xf:input
), datatype, and appearances, - checks all available control bindings in the Form Builder toolbox,
- 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.
-
XForms specifies or suggests some standard appeararances. For example, a single selection control
<xf:select1>
with apperancefull
should show as radio buttons, while thecompact
appearance should show as a dropdown menu. ↩ -
Curious developers can see the very simple implementation of the
fr:character-counter
control here. ↩ -
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. ↩
-
Mostly implemented in
BindingDescriptor.scala
andBindingOps.scala
. ↩
No comments:
Post a Comment