The source code of this page is available at

We use a library to build forms that take care of the most tedious work for us.

Characteristics (need to be updated)

  • Use an indipendend library of Form Components (elm-form-components)
  • Both the state and the configuration of the form are seriazible into Json. This can be used to save the state to local storage or to receive the configuraiton from the server, for example.
  • The form is based on a recursive structure that allows infinite configurations
  • Even if the form is recursive, the state is saved in a flat structure for easy parsing and transformation
  • Several "makers" functions can be used to generate the form in different styles
  • The library can be used with the "makers" to generate the form or without it, generating the form manually


Forms are based on two parts, a configuration and a state:

    type alias Model =
        { conf : R10.Form.Conf.Conf
        , state : R10.Form.State

These parts also contains field state and configuration for a total of four things:

  • Form Configuration
  • Field Configuration
  • Form State
  • Field State

Form Configuration

Configuration contains all the static stuff that describe a form and doesn't change while a user is editing it.

The configuration is just a list of entities:

    type alias Conf = List Entity

where Entity is a recursive basic block of the form. Entity can be an input field or a container for multiple input fields. It can also be a separator, like a title or a sub-title.

    type Entity
        = EntityNormal EntityId (List Entity)
        | EntityWrappable EntityId (List Entity)
        | R10.Form.entity.withBorder EntityId (List Entity)
        | R10.Form.entity.withTabs EntityId (List Entity)
        | R10.Form.entity.multi EntityId (List Entity)
        | EntityTitle TextSection
        | R10.Form.entity.subTitle TextSection
        | R10.Form.entity.field R10.Form.FieldConf.FieldConf

The form is like a tree where leafs are the actually input fields.

alt text

Field Configuration

The field configuration contain all static data that describe an input field:

    type alias FieldConf =
        { id : String
        , type_ : FieldType
        , label : String
        , helperText : Maybe String
        , required : Bool
        , minLength : Maybe Int
        , maxLength : Maybe Int
        , regexValidations : List RegexValidation

Form State

The form state contain all data that is changing, both at the form level and at the fields level

    type alias State =
        { fieldState : Dict.Dict String R10.Form.FieldState.FieldState
        , quantities : Quantities
        , activeTabs : ActiveTabs
        , focused : Maybe String
        , removed : Set.Set String
        , qtySubmitAttempted : QtySubmitAttempted

In details

  • fieldState is a dictionary where: the key is a special value generated by the library containing information about the position of the input field in the tree and the value is the field state.
  • quantities keep the count of how many quantity a multiplicable entity has been multiplied
  • activeTabs is used to rememebr which tab is active when R10.Form.entity.withTabs is used
  • focuesed store the key of the input field that has the focus
  • removed keep track of all items that have been removed from an multiplicable entity
  • qtySubmitAttempted counts home many time a form has been submitted. If zero, the from has never been submitted

Field State

Field state contain data that can change in an input field

    type alias FieldState =
        { lostFocusOneOrMoreTime : Bool
        , value : String
        , dirty : Bool -- Updated but not used
        , disabled : Bool
        , validation : Validation
        , showPassword : Bool -- Used only for passwords


Field types are grouped in 4 categories:

    type FieldType
        = TypeText TypeText
        | TypeBinary TypeBinary
        | TypeSingle TypeSingle (List FieldOption)
        | TypeMulti TypeMulti (List FieldOption)
  • TypeText is for types where the user is typing some text. Subtypes belonging to this category are:

      type TypeText
          = TextPlain
          | TextEmail
          | TextUsername
          | TextPasswordNew
          | TextPasswordCurrent
          | TextMultiline
  • TypeBinary is for type that allow two choices. Subtypes are:

      type TypeBinary
          = BinaryCheckbox
          | BinarySwitch
  • TypeSingle is for types that allow a single choice. Subtypes are:

      type TypeSingle
          = SingleRadio
          | SingleCombobox
  • TypeMulti is for types that allow multiple choices (not to be confused with multiline input text and not with multiple checkboxes). Subtypes are:

      type TypeMulti
          = MultiCombobox -- TODO


Keys are used to indetify nodes in the tree (and consequently, input fields). They are stored as a list of EntityId that are strings:

    type Key = Key (List String)

The are converted to string just joining all the element of the list and using a separator, usually "/".

The Form Architecture

The library provide a built in system to manage message and state changes. So, to add a form into a page is enough to create one message. You can see details in this page


"Makers" are script that take the form configuration and transorm it in something lese, called Outcome.


This maker generate Element R10.Form.Msg that is a nested view structure to display the form on the screen


This maker generate ( R10.Form.Key.Key, R10.Form.FieldConf.ValidationSpecs ) that is a flat list of all keys and validation configuration of entities.


This maker generate Form.StateForValues.Entity that is a shallow (but not flat) structure that contain all the values of the form. This structure could be close to a graphQL structure. Could also generate type (String, Bool, Int,etc.) accordingly if needed.


See below few example of forms.

Both FormState and FormConf have decoder and encoders so you can edit their JSON version below and see the result in realtime.

A simple text field
Form 1
Form 1 state Json - editable
Form 1 configuration Elm - read only
Form 1 configuration Json - editable
An email input field with validation
Form 2
Form 2 state Json - editable
Form 2 configuration Elm - read only
Form 2 configuration Json - editable
Two fields - multiple instances
Form 3
Helper text
Form 3 state Json - editable
Form 3 configuration Elm - read only
Form 3 configuration Json - editable
Radio buttons
Form 4
Used, among other things, to set the prefix of the telephone number
Country code and region
Form 4 state Json - editable
Form 4 configuration Elm - read only
Form 4 configuration Json - editable
Form 5
Social Providers
Select all social networks that you would like to activate
xxx Microsoft (Internal)
Google fjskldsjl fjds fdslfa fsdklf dklf jsla fsklf sdlf slf s fdsl fdkslf jdksf djsklfjdslfjdskl fds fdsfd ss lfdfds fd fdf dsfds fdsfdsfd
PChome fdsfdjlkfds f dslfdslf dskf dslf dsklff jdskl fjdsklfjdkslPChome fdsfdjlkfds f dslfdslf dskf dslf dsklff jdskl fjdsklfjdkslPChome fdsfdjlkfdsPChome fdsfdjlkfds f dslfdslf dskf dslf dsklff jdskl fjdsklfjdkslPChome fdsfdjlkfds f dslfdslf dskf dslf dsklff jdskl fjdsklfjdkslPChome fdsfdjlkfdsPChome fdsfdjlkfds f dslfdslf dskf dslf dsklff jdskl fjdsklfjdkslPChome fdsfdjlkfds f dslfdslf dskf dslf dsklff jdskl fjdsklfjdkslPChome fdsfdjlkfdsPChome fdsfdjlkfds f dslfdslf dskf dslf dsklff jdskl fjdsklfjdkslPChome fdsfdjlkfds f dslfdslf dskf dslf dsklff jdskl fjdsklfjdkslPChome fdsfdjlkfds f dslfdslf dskf dslf dsklff jdskl fjdsklfjdksl fjdsklf jdskl fdslf dslf fjkds fdslf jdsklf jdkl fjdlsk fdkslf dslf dsklf djskl fdjksl fdls
Form 5 state Json - editable
Form 5 configuration Elm - read only
Form 5 configuration Json - editable
Form 6
Validation error
Validation error
Form 6 state Json - editable
Form 6 configuration Elm - read only
Form 6 configuration Json - editable