Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Elm Form Validation

Elm Form Validation

Discusses the problems with form validation in Elm and presents a solution for handling form validation in a pleasant way using the Form Validator extension.

Brooke Kuhlmann

April 17, 2024
Tweet

More Decks by Brooke Kuhlmann

Other Decks in Programming

Transcript

  1. The Problem • Pages that deal with too much data

    • Repeating the same pattern over multiple forms/pages. • Repeating common validation strategies. alchemists.io
  2. Model Example (single form) type alias Model = { username:

    String, email: String, password: String, role: String, notes: String } ℹ Gets worse when you need to model data other than your form. alchemists.io
  3. Model Example (multiple forms) type alias Model = { userForm

    = UserForm, addressForm = AddressForm } type alias UserForm = { username: String, password: String } type alias AddressForm = { line1: String, country: String, state: String, zip: String } ⚠ Unwieldy! alchemists.io
  4. View Example viewUsernameField : Model -> Html Message viewUsernameField model

    = div [class "field"] [ label [for "username", class "label"] [text "Username"], input [ name "username", type_ "text", class "input", value <| model.username, onInput <| UsernameInputChange, onBlur <| UsernameInputBlur ] [] ] ℹ Necessary regardless of solution. alchemists.io
  5. Message Example type Message = UsernameInputChange String | UsernameInputBlur String

    | PasswordInputChange String | PasswordInputBlue String | EmailInputBlur String | EmailInputBlur String | Save ⚠ Unwieldy with lots of duplication. alchemists.io
  6. Update Example update : Message -> Model -> (Model, Cmd

    Message) update message model = case message of UsernameInputChange username -> ({model | username = username}, Cmd.none) UsernameInputBlur username -> ({model | username = username}, Cmd.none) -- Pattern repeats for other branches Save -> let isInvalid = String.isBlank model.username || ... in if isInvalid then ({model | formError = Just "Errors detected!"}, Cmd.none) else ({model | formError = Nothing}, Cmd.none) ℹ Doesn't begin to cover individual errors. alchemists.io