Sutil
This section will show you how to use Fable.Form
with Elmish.
Open the library modules
open Sutil open Fable.Form.Simple open Fable.Form.Simple.Sutil.Bulma open Fable.Form.Simple.Fields.Html
Define a type
Values
which is used to represents the different fields we have in the form.type Values = { Email: string Password: string RememberMe: bool }
Create the form logic:
- First create each field
- Create an
onSubmit
function which maps the result of the form into aMsg
- Tie the fields and the
onSubmit
function together
let form: Form<Values, _> = let emailField = Form.textField { Parser = fun value -> if value.Contains("@") then Ok value else Error "The e-mail address must contain a '@' symbol" Value = fun values -> values.Email Update = fun newValue values -> { values with Email = newValue } Error = fun _ -> None Attributes = TextField.create "email" |> TextField.withLabel "Email" |> TextField.withPlaceholder "some@email.com" |> TextField.withAutoFocus } let passwordField = Form.passwordField { Parser = Ok Value = fun values -> values.Password Update = fun newValue values -> { values with Password = newValue } Error = fun _ -> None Attributes = PasswordField.create "password" |> PasswordField.withLabel "Password" } let rememberMe = Form.checkboxField { Parser = Ok Value = fun values -> values.RememberMe Update = fun newValue values -> { values with RememberMe = newValue } Error = fun _ -> None Attributes = CheckboxField.create "remember-me" |> CheckboxField.withText "Remember me" } let onSubmit = fun email password rememberMe -> (email, password, rememberMe) Form.succeed onSubmit |> Form.append emailField |> Form.append passwordField |> Form.append rememberMe
Define a
State
type which will be used to represent the state of the component.[<RequireQualifiedAccess>] type State = | Filling of Form.View.Model<Values> | Filled of string * string * bool
Create a
Sutil
component and initialize its state asFilling
.absTo do so, we set the default value of each fields. Then pass the values to the function
Form.View.idle
which will returns aForm.View.Model
let Page () = let stateStore = { Email = "" Password = "" RememberMe = false } |> Form.View.idle |> State.Filling |> Store.make
Use the
stateStore
to either render the form withForm.View.asHtml
or the filled view.Bind.el ( stateStore, fun state -> match state with | State.Filling formValues -> Form.View.asHtml { OnChange = State.Filling >> (Store.set stateStore) OnSubmit = State.Filled >> Store.set stateStore Action = Form.View.Action.SubmitOnly "Sign in" Validation = Form.View.ValidateOnSubmit } form formValues | State.Filled(email, password, rememberMe) -> Html.ul [ Html.li [ Html.text $"Email: {email}" ] Html.li [ Html.text $"Password: {password}" ] Html.li [ Html.text $"Remember me: {rememberMe}" ] ] )
Congratulations ๐, you now know how to use Fable.Form
in your application with Sutil.