Generic forms almost never match the real world. If you want to change a generic form, you can either implement it from scratch, or use the projectedForm function.
As an example, we will to remove the age field from the form, and change the _isMale field to a Yes/No choice instead of a True/False choice. The datatype YesNo is defined in this module.
data PersonView = PersonView {
__name :: String
, __isMale :: YesNo
}
$(deriveAll ''PersonView "PFPersonView")
type instance PF PersonView = PFPersonView
We can now use fclabels to convert back and forth between Person and
PersonView. First, we use Template Haskell to generate some accessor functions:
$(mkLabels [''Person])
This is the bidirectional function between Person and PersonView. How to write such a function is explained in the well-documented fclabels package at http://hackage.haskell.org/package/fclabels.
toView :: Person :-> PersonView
toView = Label (PersonView <$> __name `for` name <*> __isMale `for` (boolToYesNo `iso` isMale))
Now that we have a function with type Person :-> PersonView, we can render a
form for personView and update the original person. Note that the argument is
not a Maybe value, in contrast with the gformlet function.
personForm' :: Person -> XForm Identity Person
personForm' = projectedForm toView
formHtml' :: X.Html
(_, Identity formHtml', _) = F.runFormState [] (personForm' chris)
|