Problem

You want to process a classic post form.

Solution

Yesod provides several helper functions to build forms. The most simple method is to define form data in a type and use this type to build a form in an applicative way.

{-#  OverloadedStrings #-}

data MyFormData = MyFormData
  { textSample :: Text
  , boolSample :: Bool
  , textAreaSample :: Textarea
  }

With this form data we can now start to build our form. We use here the Yesod function renderDivs to create a processable Form with our defined FormData included:

buildForm :: Form MyFormData
buildForm = renderDivs $ MyFormData
  <$> areq textField textSampleFieldSettings Nothing
  <*> areq boolField boolSampleFieldSettings Nothing
  <*> areq textAreaField textAreaSampleFieldSettings Nothing

To process our form we make use of the function runFormPost inside the handler function:

postSampleR :: Handler Html
postSampleR = do
  ((result, formWidget), enctype) <- runFormPost $ buildForm
  case result of
    FormSuccess formData -> do
      -- This is our success case branch
      setMessage "Form submitted successfully"
      return ()
    _ ->
      return ()
  defaultLayout $ do
    setTitle "Form processing sample"
    $(widgetFile "templates/form")

The last step is to define a template to render the form:

<div .container>
  <h1>Plain POST Form

  <form method=post action=@{PostSampleR} enctype=#{enctype}>
    ^{formWidget}
      <button type=submit>Submit

Discussion

TBD