composable-form 
This package allows you to build forms that are
- Composable: they can be extended and embedded in other forms.
- Type-safe: everything is safely tied together with compiler guarantees.
- Maintainable: you do not need
viewcode nor amsgfor each form field. - Concise: field validation and update logic are defined in a single place.
- Consistent: validation errors are always up-to-date with the current field values.
- Extensible: you can create your own custom fields and write custom view code.
Here is an example that defines a login form:
module Form.Login exposing (Output, Values, form)
import Data.EmailAddress as EmailAddress exposing (EmailAddress)
import Form exposing (Form)
import Form.Value exposing (Value)
type alias Values =
{ email : Value String
, password : Value String
, rememberMe : Value Bool
}
type alias Output =
{ email : EmailAddress
, password : String
, rememberMe : Bool
}
form : Form Values Output
form =
let
emailField =
Form.emailField
{ parser = EmailAddress.parse
, value = .email
, update = \value values -> { values | email = value }
, attributes =
{ label = "E-Mail"
, placeholder = "some@email.com"
}
}
passwordField =
Form.passwordField
{ parser = Ok
, value = .password
, update = \value values -> { values | password = value }
, attributes =
{ label = "Password"
, placeholder = "Your password"
}
}
rememberMeCheckbox =
Form.checkboxField
{ parser = Ok
, value = .rememberMe
, update = \value values -> { values | rememberMe = value }
, attributes =
{ label = "Remember me" }
}
in
Form.succeed Output
|> Form.append emailField
|> Form.append passwordField
|> Form.append rememberMeCheckboxRead the Form module documentation to understand how this code works.
Demo / Examples
Try out the live demo and/or check out the examples.
Contributing / Feedback
Feel free to fork and open issues or pull requests. You can also come to chat in the #forms channel on the Elm Slack, feel free to contact me (@hecrj) there!