initial commit
This commit is contained in:
commit
cfe0001846
4 changed files with 119 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
elm-stuff/
|
3
README.md
Normal file
3
README.md
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# elm experiments
|
||||||
|
|
||||||
|
a collection of various experiments to learn [Elm](https://elm-lang.org/)
|
24
elm.json
Normal file
24
elm.json
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
{
|
||||||
|
"type": "application",
|
||||||
|
"source-directories": [
|
||||||
|
"src"
|
||||||
|
],
|
||||||
|
"elm-version": "0.19.1",
|
||||||
|
"dependencies": {
|
||||||
|
"direct": {
|
||||||
|
"elm/browser": "1.0.2",
|
||||||
|
"elm/core": "1.0.5",
|
||||||
|
"elm/html": "1.0.0"
|
||||||
|
},
|
||||||
|
"indirect": {
|
||||||
|
"elm/json": "1.1.3",
|
||||||
|
"elm/time": "1.0.0",
|
||||||
|
"elm/url": "1.0.0",
|
||||||
|
"elm/virtual-dom": "1.0.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"test-dependencies": {
|
||||||
|
"direct": {},
|
||||||
|
"indirect": {}
|
||||||
|
}
|
||||||
|
}
|
91
src/PasswordValidation.elm
Normal file
91
src/PasswordValidation.elm
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
module PasswordValidation exposing (..)
|
||||||
|
import Browser
|
||||||
|
import Html exposing (..)
|
||||||
|
import Html.Attributes exposing (..)
|
||||||
|
import Html.Events exposing (onInput)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- MAIN
|
||||||
|
|
||||||
|
|
||||||
|
main =
|
||||||
|
Browser.sandbox { init = init, update = update, view = view }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- MODEL
|
||||||
|
|
||||||
|
|
||||||
|
type alias Model =
|
||||||
|
{ name : String
|
||||||
|
, password : String
|
||||||
|
, passwordAgain : String
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
init : Model
|
||||||
|
init = Model "" "" ""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- UPDATE
|
||||||
|
|
||||||
|
|
||||||
|
type Msg
|
||||||
|
= Name String
|
||||||
|
| Password String
|
||||||
|
| PasswordAgain String
|
||||||
|
|
||||||
|
|
||||||
|
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 }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- VIEW
|
||||||
|
|
||||||
|
|
||||||
|
view : Model -> Html Msg
|
||||||
|
view model =
|
||||||
|
div []
|
||||||
|
[ viewInput "text" "Name" model.name Name
|
||||||
|
, viewInput "password" "Password" model.password Password
|
||||||
|
, viewInput "password" "Re-enter Password" model.passwordAgain PasswordAgain
|
||||||
|
, viewValidation model
|
||||||
|
]
|
||||||
|
|
||||||
|
viewInput : String -> String -> String -> (String -> msg) -> Html msg
|
||||||
|
viewInput t p v toMsg =
|
||||||
|
input [ type_ t, placeholder p, value v, onInput toMsg ] []
|
||||||
|
|
||||||
|
viewValidation : Model -> Html msg
|
||||||
|
viewValidation model =
|
||||||
|
if List.length (passwordHints model.password) > 0 then
|
||||||
|
div [ style "color" "red" ] (passwordHints model.password)
|
||||||
|
else if model.password /= model.passwordAgain then
|
||||||
|
div [ style "color" "red" ] [ text "Passwords do not match!" ]
|
||||||
|
else
|
||||||
|
div [ style "color" "green" ] [ text "OK" ]
|
||||||
|
|
||||||
|
passwordHints : String -> List (Html msg)
|
||||||
|
passwordHints s =
|
||||||
|
(optional (String.length s <= 8) (text "Password must be at least 8 characters. "))
|
||||||
|
++ (optional (String.toUpper s == s) (text "Password must contain an uppercase letter. "))
|
||||||
|
++ (optional (String.toLower s == s) (text "Password must contain a lowercase letter. "))
|
||||||
|
++ (optional (not (containsNumeric s)) (text "Password must contain a number. "))
|
||||||
|
|
||||||
|
optional : Bool -> Html msg -> List (Html msg)
|
||||||
|
optional b xs = if b then [xs] else []
|
||||||
|
|
||||||
|
containsNumeric : String -> Bool
|
||||||
|
containsNumeric s = List.any (\b -> b) (List.map (\x -> String.contains x s) ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"])
|
Loading…
Reference in a new issue