We can use a Higher-Kinded
form not only for field names and values, but to
validate form fields
data UserForm f = UserForm
{ user :: Field f User
, age :: Field f Int
, pass1 :: Field f Text
, pass2 :: Field f Text
}
deriving (Generic, FromFormF, GenFields Validated, GenFields FieldName)
Write a validator for each field:
validateAge :: Int -> Validated Int
validateAge a =
validate (a < 20) "User must be at least 20 years old"
Then combine them into a record of
Validated fields
validateForm :: UserForm Identity -> UserForm Validated
validateForm u =
UserForm
{ user = validateUser u.user
, age = validateAge u.age
, pass1 = validatePass u.pass1 u.pass2
, pass2 = NotInvalid
}
We can use
fileInput to accept file uploads. These are saved to a temporary file and cleaned up after the request.
data DocumentForm f = DocumentForm
{ name :: Field f Text
, required :: Field f UploadedFile
, optional :: Field f (Maybe UploadedFile)
}
deriving (Generic, FromFormF, GenFields FieldName)
documentFormView :: View SubmitFiles ()
documentFormView = do
let f = fieldNames @DocumentForm
form Submit ~ gap 15 . pad 10 . flexCol $ do
el ~ Style.h1 $ "Upload a document"
field f.name $ do
label $ do
text "Your Name"
input Username @ placeholder "Bob" ~ Style.input
field f.required $ do
label $ do
text "Required"
fileInput
field f.optional $ do
label $ do
text "Optional"
fileInput
submit "Submit" ~ btn