I have a very simple login form with username / password. Is there a way to POST this form to the server and check for a 200s response without having to go through the coding gymnastics required to track the value of each field character by character as the user types? (Yes, I understand that it is the Elm way to do things, but adding two fields to my model, two Msg with accompanying entries in update just seems like a lot of unneeded code for a simple login form, and storing the password in the model forever seems like a bad idea.)
I have read these two questions, and I have found the onSubmit
event. However, I am not sure what to do once update
receives the message that the onSubmit
event has fired. I feel like there might be two ways forward and I can't figure out how to do either:
I would use the default submit function, but I would prefer to login with an asynchronous request and not leave the page.
Although I would do the gymnastics for this case, you can do another gymnastics with JSON decoder to get values from DOM and put them into a Msg. JSON decoder allows you to get any values from event object with JSON decoder as long as it’s property access instead of method call.
Another trick is that you can access input elements by name from the form element.
import Html exposing (Html)
import Html.Attributes as HA
import Html.Events as HE
import Json.Decode as Json exposing (Decoder)
type Msg
= SubmitLogin String String
update : Msg -> Model -> Model
update msg model =
case msg of
SubmitLogin username password ->
-- Do AJAX with username and password
decodeField : String -> Decoder String
decodeField name =
Json.at
[ "currentTarget"
, name
, "value"
]
Json.string
decodeLoginForm : Decoder Msg
decodeLoginForm =
Json.map2
SubmitLogin
(decodeField "username")
(decodeField "password")
preventDefault : HE.Options
preventDefault =
{ preventDefault = True
, stopPropagation = False
}
onLoginSubmit : Html.Attribute Msg
onLoginSubmit =
HE.onWithOptions
"submit"
preventDefault
decodeLoginForm
view : Model -> Html.Html Msg
view model =
Html.form
[ onLoginSubmit ]
[ Html.input
[ HA.name "username"
, HA.type_ "text"
]
[]
, Html.input
[ HA.name "password"
, HA.type_ "password"
]
[]
, Html.input
[ HA.type_ "submit"
, HA.value "Login"
]
[]
]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With