I'm trying to have a registration form with fields like email
and emailConfirmation
, or password
and passwordConfirmation
. Validating email
and password
is easy, there are rules and I've written the respective functions.
The other two are harder though. I found this question and tried writing my code like this:
The form definition, using Blaze:
registrationForm :: (View Html) -> Html
registrationForm view = docTypeHtml $ do
form ! name "registration" ! method "post" ! action "/register" $ do
fieldset $ do
label ! for "password" $ (text "Password")
inputText "password" view
errorList "password" view
br
label ! for "passwordConfirmation" $ (text "Password Confirmation")
inputText "passwordConfirmation" view
errorList "passwordConfirmation" view
and the validator:
data Password = Password { password :: Text }
validateForm :: Monad m => Form Html m Password
validateForm =
Password
<$> "password" .: validatePassword
where
validatePassword =
validate fst' $ (,) <$> ("password" .: D.text Nothing)
<*> ("passwordConfirmation" .: D.text Nothing)
fst' (p1, p2) | p1 == p2 = Success p1
| otherwise = Error "Passwords must match"
But whenever I run the server I get a message saying "password is not a field". If I remove the validation and give password
a simple validation, then it works as expected. Am I missing something here?
I got help on the digestive-functors repository. Thanks cimmanon
This is the final code, note field name is now "password.p1"/"password.p2" instead of just password/passwordConfirmation.
registrationForm :: (View Html) -> Html
registrationForm view = docTypeHtml $ do
form ! name "registration" ! method "post" ! action "/register" $ do
fieldset $ do
inputText "password.p1" view
br
inputText "password.p2" view
errorList "password" view
data Password = Password { password :: Text }
validator is the same, except for new names:
validateForm :: Monad m => Form Html m Password
validateForm =
Password
<$> "password" .: validatePassword
where
validatePassword =
validate fst' $ (,) <$> ("p1" .: D.text Nothing)
<*> ("p2" .: D.text Nothing)
fst' (p1, p2) | p1 == p2 = Success p1
| otherwise = Error "Passwords must match"