I'm happy to announce the release of dwayne/elm-field
.
dwayne/elm-field
is an Elm package for constructing valid data from unreliable string inputs. It provides a Field
data structure that models the non-UI related aspects of an input field. I extracted this package from my work on L-System Studio.
Think about a Field
in a similar way as you'd think about Maybe
, Result
, and Validation
. Suppose you're parsing a String
into a value of some type, say a
. There's the potential for one or more errors to occur. If you just want to know that an error occurred but you don't care about the specific error that occurred you'd use Maybe
. If you do care to track the specific errors then you'd switch to Result
. Furthermore, if you care to accumulate multiple specific errors you'd change to a Validation
.
A Field
is like a Validation
in that it allows you to accumulate multiple specific errors. But, it also does a little bit more.
- It remembers the original raw
String
you were trying to parse. - It remembers whether or not it's the first time you're changing the
String
to be parsed, i.e. whether or not your field is clean or dirty. - It keeps track of the function used to parse the
String
. And, - It keeps track of the function used to convert the value back to a
String
.
The last two constitute the Type
of a Field
.
The package provides two modules: Field
and Field.Advanced
. The difference between them is that Field.Advanced
allows you to use a custom type to track your errors whereas Field
uses strings for errors.
An example
Suppose you need to accept input from a user for a positive integer, i.e. an integer greater than or equal to 1. Here's what that might look like:
import Field as F exposing (Field)
...
type alias Model =
{ n : Field Int
, ...
}
init : Model
init =
{ n = F.empty F.positiveInt
, ...
}
type Msg
= Input String
| ...
update : Msg -> Model -> Model
update msg model =
case msg of
Input s ->
{ model | n = F.setFromString s model.n }
...
view : Model -> H.Html Msg
view model =
...
H.input
[ HA.type_ "text"
, HA.value (F.toRawString model.n)
, ...
, HE.onInput Input
]
[]
...
In general, you can easily create a field out of any of Elm's primitive types: Int
, Float
, Bool
, Char
, and String
.
For many more examples you can read the README, play with the demos, and examine the unit tests.
No UI
I want to stress that a Field
data structure models the non-UI related aspects of an input field. This means you can implement the business logic for a form and reuse that logic to render your form in infinitely many ways. Take the sign up form example. The simple view and the complex view are different renderings of the same underlying form. You have complete control over the UI.
Richard's comment
If you resonate with Richard's comment then my package attempts to provide a better tool for working with forms as programs. Give it a try and let me know what you think.
Subscribe to my newsletter
If you're interested in improving your skills with Elm then I invite you to subscribe to my newsletter, Elm with Dwayne. To learn more about it, please read this announcement.