Useful things to build a form .
A form is defined by the configuration (R10.Form.Conf) that contain data about the input fields, radio buttons, etc. and the state (R10.Form.State), containing instead all the values and other parameters that change during the life of the form.
type alias Form =
{ conf : R10.Form.Conf
, state : R10.Form.State
}There are four functions to render a Form, each with a different degree of customization. They are order from the simplest (less customizable) to the most complex (more customizable).
This is the simplest way to render a form, as you can see in this minimalistic example:
module Main exposing (main)
import Element exposing (..)
import Html
import R10.Form
import R10.FormTypes
formModel : R10.Form.Form
formModel =
{ conf =
[ R10.Form.entity.field
{ id = "email"
, idDom = Nothing
, type_ = R10.FormTypes.TypeText R10.FormTypes.TextEmail
, label = "Email"
, helperText = Just "My first form"
, requiredLabel = Nothing
, validationSpecs = Nothing
}
]
, state = R10.Form.initState
}
formMsgMapper : R10.Form.MsgMapper ()
formMsgMapper =
\_ -> ()
main : Html.Html ()
main =
layout [] <|
column [ centerX, centerY ] <|
R10.Form.view formModel formMsgMapperNote that the form of this example is not active because it is just rendering the view but it is not wired to The Elm Architecture. If interested, look at the code of an active form example.
Use this version if you have R10.Theme.Theme.
Use this version if you have a specific palette that you want to use.
Use this version for full control.
These are the options that you can use with viewWithOptions.
This function required by all views is used to convert specific form messages (Msg) into generic messages (msg). Tipically you would define this function like this in your application:
type Msg
= MsgForm R10.Form.Internal.MsgMsgForm can now be used as MsgMapper that convert R10.Form.Internal.Msg into Msg.
For a code example have a look at this simple form.
This function can be used to do some processing before the form get submitted.
It returns True when the form is submittable and the message is Submit. To be used in the update function.
State is the equivalent of the Model in a TEA structure.
It contains the values and the other things that ususally change while the user is interacting with the form.
The state is defined as
type alias State =
{ fieldsState : Dict KeyAsString FieldState
, multiplicableQuantities : Dict KeyAsString Int
, activeTabs : Dict KeyAsString String
, focused : Maybe KeyAsString
, active : Maybe KeyAsString
, removed : Set KeyAsString
, qtySubmitAttempted : QtySubmitAttempted
, changesSinceLastSubmissions : Bool
}Where:
fieldState is a dictionary containing the states of all fields.multiplicableQuantities is a dictionary containin the quantity of a multiplicable field. A multiplicable field is a field that the user can clone to add extra information.activeTabs describe which tab is active in case tabs are used to group objects of the form.focused is the focused element of the form at the present moment.active... what is active?removed contains multiplicable input fields that have been removed by the user.qtySubmitAttempted is the number of times that the user tried to submit the form.changesSinceLastSubmissions is True if the user changed something after the last for submission.This can be useful to store the state of a form to the Local Storage, for example. Then, using stringToState is possible to restore all the values of a form or keep the form sync'ed on different tabs.
This is the update function to wire the form in your existing TEA structure.
It consider the State of the form as the Model in a standard TEA structure, as usually is the State that change while the user interact with the form.
But, differently from the standard TEA, the view function of this form library also require the configuration of the form.
This means that if you want to go crazy and also change the configuration, you can do it. For example you could change the validations on the flight while user is changing a value. Or you can add new input fields, etc. See fieldConfigConcatMap for this type of usage.
The configuration of a form (Conf) is simply defined as a list of entities (List Entity).
A form is made of multiple entities. An example of entity is an input field, a title, a subtitle, etc.
These are entities constructors
Stringtype alias TextConf =
{ title : String
, helperText : Maybe String
, validationSpecs : Maybe ValidationSpecs
}Singular fields, similarly to forms, have their own Configuration and State.
type alias FieldConf =
{ id : FieldId
, idDom : Maybe String
, type_ : R10.FormTypes.FieldType
, label : String
, helperText : Maybe String
, requiredLabel : Maybe String
, validationSpecs : Maybe ValidationSpecs
}type alias FieldState =
{ lostFocusOneOrMoreTime : Bool
, value : String
, search : String
, select : String
, scroll : Float
, dirty : Bool
, disabled : Bool
, validation : Validation
, showPassword : Bool -- Used only for passwords
}Key is internally defined as a list of strings.
The form is rapresented internally as a tree and the Key is the path to reach a node.
Get
Set
Others
This function return True in one of these two cases
This function is normally used to disble or not the submit button.
If you want to personalise the translations or you want to translate them in different languages, you can do so defining a function like
translator : Key -> ValidationCode -> String
translator key validationCode =
Dict.fromList
[ ( validationCodes.emailFormatInvalid
, "Invalid email format"
)
, ( validationCodes.emailFormatValid
, "Valid email format"
)
...
, ( validationCodes.oneOf
, "All of the validations have failed"
)
]
|> Dict.get validationCode
|> Maybe.withDefault validationCodeJust a String
Utility that can be used to change the configuration of a form on the fly. It can be useful if certain state value of the form can influence some of the validation of the form itself.
For example a Japanese address field can require to have at least one digit in it (called "Banchi", a building number). But some address may be missing this number so we give the user to opt-out from a building number requirement if the click on a check box.
Utility that can be used to iterate through the entire form configuration and returns a list of results