[Forms] Make either of two fields required

74 views
Skip to first unread message

Vincent Ambo

unread,
May 27, 2012, 5:45:43 PM5/27/12
to yeso...@googlegroups.com
Hej,

I'm building a form (monadic in case that matters) which, among other things, has a field for a telephone number and a field for a mail address. Only one of the two is required but both are okay as well.

Is there any way to represent this relation in Yesod?

Cheers,
Vincent

Michael Snoyman

unread,
May 28, 2012, 12:46:44 AM5/28/12
to yeso...@googlegroups.com
You'd really need to define a special datatype to represent that, such as:

data Contact = JustTelephone Telephone | JustAddress Address |
Both Telephone Address

Then you could write some kind of a function to combine them:

makeContact :: FormResult (Maybe Telephone) -> FormResult (Maybe
Address) -> FormResult Contact
makeContact fmt fma =
go $ (,) <$> fmt <*> fma
where
go (FormSuccess (mt, ma)) =
case (mt, ma) of
(Nothing, Nothing) -> FormFailure ["You must provide
either a telephone number or mailing address."]
(Just t, Just a) -> FormSuccess $ Both t a
...
go (FormFailure es) = FormFailure es
go FormMissing = FormMissing

Michael

Max Cantor

unread,
May 28, 2012, 1:51:26 PM5/28/12
to yeso...@googlegroups.com
You could also write a custom field (as in www.yesodweb.com/book/forms )

passwordConfirmField :: Field sub master Text passwordConfirmField = Field { fieldParse = \rawVals -> case rawVals of [a, b] | a == b -> return $ Right $ Just a | otherwise -> return $ Left "Passwords don't match" [] -> return $ Right Nothing _ -> return $ Left "You must enter two values" , fieldView = \idAttr nameAttr _ eResult isReq -> [whamlet| <input id=#{idAttr} name=#{nameAttr} type=password> <div>Confirm: <input id=#{idAttr}-confirm name=#{nameAttr} type=password> |] } getRootR :: Handler RepHtml getRootR = do ((res, widget), enctype) <- runFormGet $ renderDivs $ areq passwordConfirmField "Password" Nothing defaultLayout [whamlet| <p>Result: #{show res} <form enctype=#{enctype}> ^{widget} <input type=submit value="Change password"> |] main :: IO () main = warpDebug 3000 Password

Vincent Ambo

unread,
May 30, 2012, 12:59:24 PM5/30/12
to yeso...@googlegroups.com
I actually like the custom field idea a lot, I'll go with that! 

Thanks to both of you :-)
Reply all
Reply to author
Forward
0 new messages