Takao
Takao

Reputation: 1016

Creation of monadic yesod form without hamlet

My goal is to write a monadic yesod form without usage of hamlet.

Let's say I have such example form:

userForm :: Maybe User -> Html -> MForm Handler (FormResult User, Widget)
userForm u extra = do
  (nameR, nameV) <- mreq textField "" (userName <$> u)
  (passR, passV) <- mreq passwordField "" Nothing
  let userRes = User <$> nameR <*> passR
  let widget = do
    toWidget $ \render -> do
      extra
      -- fvInput nameV?
      -- fvInput passV?
      H.input ! type_ "submit" ! value "Submit"
  return (userRes, widget)

In the case of hamlet usage it will be like that:

let widget = do
  toWidget [whamlet|
            ^{fvInput nameV}
            ^{fvInput passV}
           |]

But the return type of fvInput is FieldView App and I need to convert it to Html to compose with blaze well.

Perhaps, it will be easier to use Input Form for this task(i.e. implementing forms without w/hamlet), but the docs on yesodbook say it doesn't have a proper handling of the wrong input case. I tend to use monadic form here since I want a recreation of user input in the case of failed validation "for free" here. Will it work this way?

Upvotes: 1

Views: 103

Answers (1)

ErikR
ErikR

Reputation: 52057

Use lift with widgetToPageContent:

userForm :: Maybe MyUser -> Html -> MForm Handler (FormResult MyUser, Widget)
userForm u extra = do
  (nameR, nameV) <- mreq textField "" (myUserName <$> u)
  (passR, passV) <- mreq passwordField "" Nothing
  nameContents <- lift $ widgetToPageContent (fvInput nameV)
  passContents <- lift $ widgetToPageContent (fvInput passV)
  let userRes = MyUser <$> nameR <*> passR
  let widget = do
        toWidget $ \render -> do
          extra
          pageBody nameContents render
          pageBody passContents render
          H.input H.! A.type_ "submit" H.! A.value "Submit"
  return (userRes, widget)

Upvotes: 1

Related Questions