Created
November 12, 2016 18:47
-
-
Save jedschneider/dd8148969424b1c9fb5b9d2894b604a7 to your computer and use it in GitHub Desktop.
completed extra exercises for https://guide.elm-lang.org/architecture/user_input/forms.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Main exposing (..) | |
import Html exposing (..) | |
import Html.App as Html | |
import Html.Attributes exposing (..) | |
import Html.Events exposing (onInput, onClick) | |
import String exposing (..) | |
import Char | |
import Maybe | |
main = | |
Html.beginnerProgram { model = model, view = view, update = update } | |
-- MODEL | |
type alias Model = | |
{ name : String | |
, password : String | |
, passwordAgain : String | |
, age : String | |
, validationResult : ValidationResult | |
} | |
type ValidationResult | |
= NotDone | |
| Error String | |
| ModelOk | |
model : Model | |
model = | |
Model "" "" "" "" NotDone | |
-- UPDATE | |
type Msg | |
= Name String | |
| Password String | |
| PasswordAgain String | |
| Age String | |
| Submit | |
update : Msg -> Model -> Model | |
update msg model = | |
case msg of | |
Name name -> | |
{ model | name = name } | |
Password password -> | |
{ model | password = password } | |
PasswordAgain password -> | |
{ model | passwordAgain = password } | |
Age age -> | |
{ model | age = age } | |
Submit -> | |
{ model | validationResult = validate model } | |
-- VIEW | |
view : Model -> Html Msg | |
view model = | |
div [] | |
[ input [ type' "text", placeholder "Name", onInput Name ] [] | |
, input [ type' "text", placeholder "Age", onInput Age ] [] | |
, input [ type' "password", placeholder "Password", onInput Password ] [] | |
, input [ type' "password", placeholder "Re-enter Password", onInput PasswordAgain ] [] | |
, button [ onClick Submit ] [ text "Submit" ] | |
, viewValidation model | |
] | |
viewValidation : Model -> Html msg | |
viewValidation model = | |
let | |
( color, message ) = | |
case model.validationResult of | |
NotDone -> | |
( "", "" ) | |
ModelOk -> | |
( "green", "OK" ) | |
Error msg -> | |
( "red", msg ) | |
in | |
div [ style [ ( "color", color ) ] ] [ text message ] | |
-- HELPERS | |
validate : Model -> ValidationResult | |
validate model = | |
let | |
validations = | |
[ (passwordsMatch model.password model.passwordAgain) | |
, (passwordLongEnough model.password) | |
, (containsNumeric model.password) | |
, (containsUpcase model.password) | |
, (containsLower model.password) | |
, (isNumber model.age) | |
] | |
messages = | |
List.filterMap identity validations | |
valid = | |
List.isEmpty messages | |
in | |
case valid of | |
True -> | |
ModelOk | |
False -> | |
Error (join " " messages) | |
-- VALIDATIONS | |
isNumber : String -> Maybe String | |
isNumber str = | |
case String.toInt str of | |
Ok _ -> | |
Nothing | |
Err _ -> | |
Just "Age must be a number" | |
passwordsMatch : String -> String -> Maybe String | |
passwordsMatch str again = | |
case str == again of | |
False -> | |
Just "Passwords do not match!" | |
True -> | |
Nothing | |
passwordLongEnough : String -> Maybe String | |
passwordLongEnough password = | |
case (String.length password) >= 8 of | |
False -> | |
Just "Password is not long enough!" | |
True -> | |
Nothing | |
hasCharType : (Char -> Bool) -> String -> String -> Maybe String | |
hasCharType fn msg password = | |
case String.any fn password of | |
False -> | |
Just msg | |
True -> | |
Nothing | |
containsNumeric = | |
hasCharType Char.isDigit "Must contain number!" | |
containsUpcase = | |
hasCharType Char.isUpper "Password must contain upper case letter!" | |
containsLower = | |
hasCharType Char.isLower "Password must contain lower case letter!" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment