Last active
December 8, 2016 16:11
-
-
Save bsermons/ff11bf2fdd2f3a02642d to your computer and use it in GitHub Desktop.
Elm login example
This file contains hidden or 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 Login where | |
| import Html exposing (..) | |
| import Html.Attributes exposing (..) | |
| import Html.Events exposing (on, onClick, targetValue) | |
| import Http | |
| import Json.Encode as Encode exposing (encode) | |
| import Json.Decode as Decode | |
| import String | |
| import Task exposing (Task, andThen, onError) | |
| import Debug | |
| type Actions | |
| = NoOp | |
| | UpdateLogin String | |
| | UpdatePassword String | |
| | PostMessage String | |
| | ShowErrors | |
| type alias LoginViewModel = | |
| { login : String | |
| , password : String | |
| , signinAttempts : Int | |
| , message : Maybe String | |
| } | |
| emptyModel = | |
| { login = "" | |
| , password = "" | |
| , signinAttempts = 0 | |
| , message = Nothing | |
| } | |
| loginUrl = | |
| "http://localhost/login" | |
| getErrors {login, password} = | |
| let errors = | |
| [ (String.isEmpty login, "Login is required.") | |
| , (String.isEmpty password, "Password is required.") | |
| ] | |
| in | |
| List.filterMap (\(erred, msg) -> if erred then Just msg else Nothing) errors | |
| errItem msg = | |
| div [] [ text msg ] | |
| onChange action = | |
| on "change" targetValue (Signal.message actions.address << action) | |
| field lbl typ action = | |
| let lblWidth = style [("width", "120px")] | |
| in | |
| div [] [ label [ for lbl, lblWidth ] [ text lbl ] | |
| , input [ name lbl, type' typ, onChange action ] [] | |
| ] | |
| encode model = | |
| Encode.encode 0 (Encode.object | |
| [ ("login", Encode.string model.login) | |
| , ("password", Encode.string model.password) | |
| ]) | |
| loginSuccessHandler resp = | |
| let _ = Debug.log "INFO(resp)" resp | |
| in | |
| Signal.send actions.address (PostMessage "Thanks for logging in.") | |
| loginErrorHandler err = | |
| let _ = Debug.log "INFO(err)" "ERROR" | |
| in | |
| Signal.send actions.address (PostMessage "Something went wrong.") | |
| login model = | |
| (Http.fromJson Decode.string | |
| (Http.send Http.defaultSettings | |
| { verb = "POST" | |
| , headers = [("Content-Type", "application/json")] | |
| , url = loginUrl | |
| , body = Http.string (encode model) | |
| })) | |
| `andThen` loginSuccessHandler | |
| `onError` loginErrorHandler | |
| loginClick model = | |
| onClick taskMailbox.address (login model) | |
| view : LoginViewModel -> Html | |
| view model = | |
| let errors = getErrors model | |
| viewErrors = if model.signinAttempts > 0 | |
| then List.map errItem errors | |
| else [] | |
| message = case model.message of | |
| Nothing -> div [] [] | |
| Just msg -> div [] [ text msg ] | |
| clickHandler = if List.length errors == 0 | |
| then loginClick model | |
| else (onClick actions.address ShowErrors) | |
| in | |
| div [] | |
| [ h1 [] [ text "Sign In1" ] | |
| , message | |
| , field "Login" "text" UpdateLogin | |
| , field "Password" "password" UpdatePassword | |
| , button [ clickHandler ] [ text "Login" ] | |
| , div [ class "errors" ] viewErrors | |
| ] | |
| update action model = | |
| case Debug.log "INFO" action of | |
| UpdateLogin val -> | |
| { model | login <- val } | |
| UpdatePassword val -> | |
| { model | password <- val } | |
| ShowErrors -> | |
| { model | signinAttempts <- model.signinAttempts + 1} | |
| PostMessage msg -> | |
| { model | | |
| signinAttempts <- model.signinAttempts + 1, | |
| message <- Just msg } | |
| actions = | |
| Signal.mailbox NoOp | |
| taskMailbox = | |
| Signal.mailbox (Task.succeed ()) | |
| port requestPort : Signal (Task x ()) | |
| port requestPort = | |
| taskMailbox.signal | |
| model = | |
| Signal.foldp update emptyModel actions.signal | |
| main = | |
| Signal.map view model |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment