Skip to content

Instantly share code, notes, and snippets.

@kamioftea
Created July 13, 2016 12:08
Show Gist options
  • Save kamioftea/8def547c270ae8a382ef8f18f7853fab to your computer and use it in GitHub Desktop.
Save kamioftea/8def547c270ae8a382ef8f18f7853fab to your computer and use it in GitHub Desktop.
Work from (def shef) elm workshop
import Html exposing (..)
import Html.App as App
import Html.Attributes exposing (..)
import Html.Events exposing (onInput,onClick)
import String
main =
App.beginnerProgram
{ model = model
, view = view
, update = update
}
-- MODEL
type alias Data =
{ name : String
, password : String
, passwordAgain : String
, age : Maybe Int
}
type alias Model =
{ live: Data
, submitted: Maybe Data
}
model : Model
model =
{ live =
{ name = ""
, password = ""
, passwordAgain = ""
, age = Nothing
}
, submitted = Nothing
}
-- UPDATE
type Msg
= Name String
| Password String
| PasswordAgain String
| Age String
| Validate
update : Msg -> Model -> Model
update msg model =
case msg of
Name name ->
{ model | live = { model.live | name = name } }
Password password ->
{ model | password = password }
PasswordAgain password ->
{ model | passwordAgain = password }
Age age ->
{ model | age = age |> String.toInt |> Result.toMaybe }
Validate ->
let
errors =
validators
|> List.map (\v -> v model)
|> List.filterMap identity
in
{ model | errors = Just errors }
-- VIEW
view : Model -> Html Msg
view model =
div []
[ input [ type' "text", placeholder "Name", onInput Name ] []
, input [ type' "password", placeholder "Password", onInput Password ] []
, input [ type' "password", placeholder "Re-enter Password", onInput PasswordAgain ] []
, input [ type' "number", placeholder "Age", onInput Age ] []
, button [ type' "button", onClick Validate ] [text "Check"]
, viewValidation model
]
validator : String -> (Model -> Bool) -> (Model -> Maybe String)
validator msg predicate =
\model -> if(predicate model) then Just msg else Nothing
validators: List (Model -> Maybe String)
validators =
[ validator "Passwords do not match!" (\model -> model.password /= model.passwordAgain)
, validator "Passwords needs to be 8 or more characters!" (\model -> String.length model.password < 8)
, validator "Age must be positive" (\model -> model.age |> Maybe.map (\age -> age < 0) |> (Maybe.withDefault True) )
]
viewValidation : Model -> Html msg
viewValidation model =
let
(colour, elem) =
case model.errors of
Nothing -> ("orange", text "Please fill in the form")
Just [] -> ("green", text "Ok")
Just errors -> ("red", ul [] (List.map (\error -> li [] [text error]) errors))
in
div [ style [("color", colour)] ] [elem]
{--
Exercises: One cool thing about breaking viewValidation out is that it is pretty
easy to augment. If you are messing with the code as you read through this
(as you should be!) you should try to:
Check that the password is longer than 8 characters.
Make sure the password contains upper case, lower case, and numeric characters.
Add an additional field for age and check that it is a number.
Add a "Submit" button. Only show errors after it has been pressed.
Be sure to use the helpers in the String library if you try any of these!
Also, we need to learn more before we start talking to servers, so before
you try that here, keep reading until HTTP is introduced. It will be significantly
easier with proper guidance! -}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment