Skip to content

Instantly share code, notes, and snippets.

@avrittrohwer
Last active July 13, 2018 04:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save avrittrohwer/21ae6cd4c7c90de7984286f00f2128fd to your computer and use it in GitHub Desktop.
Save avrittrohwer/21ae6cd4c7c90de7984286f00f2128fd to your computer and use it in GitHub Desktop.
Completed forms exercises from elm book
-- context can be found at https://guide.elm-lang.org/architecture/user_input/forms.html
module Main exposing (..)
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import Regex exposing (contains, regex)
main =
Html.beginnerProgram { model = model, view = view, update = update }
-- model
type alias Model =
{ name : String
, age : Int
, password : String
, passwordAgain : String
, conditions :
List ( { password : String, passwordAgain : String } -> Bool, String )
, showViolations : Bool
}
model : Model
model =
Model
""
0
""
""
[ ( \{ password } -> String.length password > 8
, "Password must contain more than 8 characters"
)
, ( \{ password } -> Regex.contains (regex "[A-Z]+") password
, "Password must contain at least one upper case character"
)
, ( \{ password } -> Regex.contains (regex "[a-z]+") password
, "Password must contain at least one lower case character"
)
, ( \{ password } -> Regex.contains (regex "[\\d]+") password
, "Password must contain at least one digit"
)
, ( \{ password, passwordAgain } -> password == passwordAgain
, "Passwords must match"
)
]
False
-- update
type Msg
= Name String
| Age String
| Password String
| PasswordAgain String
| Submit
update : Msg -> Model -> Model
update msg model =
case msg of
Name name ->
{ model | name = name }
Age age ->
{ model | age = Result.withDefault 0 (String.toInt age) }
Password password ->
{ model | password = password }
PasswordAgain password ->
{ model | passwordAgain = password }
Submit ->
{ model | showViolations = True }
-- view
view : Model -> Html Msg
view model =
div []
[ input [ type_ "text", placeholder "Name", onInput Name ] []
, input [ type_ "number", placeholder "Age", onInput Age ] []
, input
[ type_ "password"
, placeholder "Password"
, onInput Password
]
[]
, input
[ type_ "password"
, placeholder "Confirm password"
, onInput PasswordAgain
]
[]
, input
[ type_ "submit"
, placeholder "Submit"
, onClick Submit
]
[]
, viewValidation model
]
viewValidation : Model -> Html Msg
viewValidation model =
let
violations =
if model.showViolations then
produceViolations model
else
[]
( message, color ) =
if List.length violations > 0 then
( "Errors:", "red" )
else
( "Ok", "green" )
in
div []
[ h3 [ style [ ( "color", color ) ] ] [ text message ]
, ul []
(List.map
(\errorMsg -> li [] [ text errorMsg ])
violations
)
]
produceViolations : Model -> List String
produceViolations { password, passwordAgain, conditions } =
List.filterMap
(\( predicate, errorMsg ) ->
if
not
(predicate
{ password = password, passwordAgain = passwordAgain }
)
then
Just errorMsg
else
Nothing
)
conditions
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment