Skip to content

Instantly share code, notes, and snippets.

@jedschneider
Created November 12, 2016 18:47
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 jedschneider/dd8148969424b1c9fb5b9d2894b604a7 to your computer and use it in GitHub Desktop.
Save jedschneider/dd8148969424b1c9fb5b9d2894b604a7 to your computer and use it in GitHub Desktop.
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