Skip to content

Instantly share code, notes, and snippets.

@daniula
Last active April 15, 2018 10:23
Show Gist options
  • Save daniula/2cd14564b616bc89893f0d3be2c18588 to your computer and use it in GitHub Desktop.
Save daniula/2cd14564b616bc89893f0d3be2c18588 to your computer and use it in GitHub Desktop.
module SignupForm exposing (..)
-- This is where our Elm logic lives.`module SignupForm` declares that this is
-- the SignupForm module, which is how other modules will reference this one
-- if they want to import it and reuse its code.
-- Elm’s "import" keyword works similarly to "require" in node.js.
import Html exposing (..)
-- The “exposing (..)” option says that we want to bring the Html module’s contents
-- into this file’s current namespace, so that instead of writing out
-- Html.form and Html.label we can use "form" and "label" without the "Html."
import Html.Events exposing (..)
-- This works the same way; we also want to import the entire
-- Html.Events module into the current namespace.
import Html.Attributes exposing (id, type_, for, value, class)
-- With this import we are only bringing a few specific functions into our
-- namespace, specifically "id", "type'", "for", "value", and "class".
import Http
import Task exposing (Task)
import Json.Decode exposing (succeed)
view model =
form [ id "signup-form", onSubmit { msgType = "VALIDATE", payload = "" } ]
[ h1 [] [ text "Sensational Signup Form" ]
, label [ for "username-field" ] [ text "username: " ]
, input
[ id "username-field"
, type_ "text"
, value model.username
, onInput (\str -> { msgType = "SET_USERNAME", payload = str })
]
[]
, div [ class "validation-error" ] [ text (viewUsernameErrors model) ]
, label [ for "password" ] [ text "password: " ]
, input
[ id "password-field"
, type_ "password"
, value model.password
, onInput (\str -> { msgType = "SET_PASSWORD", payload = str })
]
[]
, div [ class "validation-error" ] [ text model.errors.password ]
, button [ class "signup-button", type_ "submit" ] [ text "Sign Up!" ]
]
viewUsernameErrors model =
if model.errors.usernameTaken then
"That username is taken!"
else
model.errors.username
-- Take a look at this starting model we’re passing to our view function.
-- Note that in Elm syntax, we use = to separate fields from values
-- instead of : like JavaScript uses for its object literals.
getErrors model =
{ username =
if model.username == "" then
"Please enter a username!"
else
""
, password =
if model.password == "" then
"Please enter a password!"
else
""
, usernameTaken = model.errors.usernameTaken
}
update msg model =
if msg.msgType == "VALIDATE" then
let
url =
"https://api.github.com/users/" ++ model.username
handleResponse result =
case result of
Ok _ ->
{ msgType = "USERNAME_TAKEN", payload = "" }
Err _ ->
{ msgType = "USERNAME_AVAILABLE", payload = "" }
request =
Http.get url (succeed "")
cmd =
Http.send handleResponse request
in
( { model | errors = getErrors model }, cmd )
else if msg.msgType == "SET_USERNAME" then
( { model | username = msg.payload }, Cmd.none )
else if msg.msgType == "SET_PASSWORD" then
( { model | password = msg.payload }, Cmd.none )
else if msg.msgType == "USERNAME_TAKEN" then
( withUsernameTaken True model, Cmd.none )
else if msg.msgType == "USERNAME_AVAILABLE" then
( withUsernameTaken False model, Cmd.none )
else
( model, Cmd.none )
withUsernameTaken isTaken model =
let
currentErrors =
model.errors
newErrors =
{ currentErrors | usernameTaken = isTaken }
in
{ model | errors = newErrors }
initialErrors =
{ username = "", password = "", usernameTaken = False }
initialModel =
{ username = "", password = "", errors = initialErrors }
main =
Html.program
{ init = ( initialModel, Cmd.none )
, view = view
, update = update
, subscriptions = always Sub.none
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment