-
Notifications
You must be signed in to change notification settings - Fork 27
Expand file tree
/
Copy pathFormParser.purs
More file actions
89 lines (82 loc) · 2.66 KB
/
FormParser.purs
File metadata and controls
89 lines (82 loc) · 2.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
module Examples.FormParser where
import Prelude
import Text.Smolder.HTML.Attributes as A
import Control.Monad.Indexed.Qualified as Ix
import Control.Monad.Indexed ((:>>=), (:*>))
import Effect (Effect)
import Effect.Class (liftEffect)
import Effect.Console (log)
import Data.Either (Either(Right, Left))
import Data.HTTP.Method (Method(..))
import Data.Maybe (Maybe(Nothing, Just))
import Data.MediaType.Common (textHTML)
import Data.String (length)
import Hyper.Form (parseForm, required)
import Hyper.Node.Server (defaultOptionsWithLogging, runServer)
import Hyper.Request (getRequestData)
import Hyper.Response (closeHeaders, contentType, respond, writeStatus)
import Hyper.Status (statusBadRequest, statusMethodNotAllowed, statusOK)
import Text.Smolder.HTML (button, form, input, label, p)
import Text.Smolder.Markup (text, (!))
import Text.Smolder.Renderer.String (render)
main :: Effect Unit
main =
let
-- A view function that renders the name form.
renderNameForm err = do
form ! A.method "post" $ do
formattedError
formElements
where
formElements = do
label ! A.for "firstName" $ text "Your Name:"
p (input ! A.name "firstName" ! A.id "firstName")
p (button (text "Send"))
formattedError =
case err of
Just s -> p ! A.style "color: red;" $ text s
Nothing -> pure unit
htmlWithStatus status x = Ix.do
writeStatus status
contentType textHTML
closeHeaders
respond (render x)
handlePost =
parseForm :>>=
case _ of
Left err -> do
liftEffect (log err)
:*> htmlWithStatus
statusBadRequest
(p (text "Bad request, invalid form."))
Right form ->
case required "firstName" form of
Right name
| length name > 0 ->
htmlWithStatus
statusOK
(p (text ("Hi " <> name <> "!")))
| otherwise ->
htmlWithStatus
statusBadRequest
(renderNameForm (Just "Name cannot be empty."))
Left err ->
htmlWithStatus
statusBadRequest
(renderNameForm (Just err))
-- Our (rather primitive) router.
router =
_.method <$> getRequestData :>>=
case _ of
Left GET ->
htmlWithStatus
statusOK
(renderNameForm Nothing)
Left POST ->
handlePost
method ->
htmlWithStatus
statusMethodNotAllowed
(text ("Method not supported: " <> show method))
-- Let's run it.
in runServer defaultOptionsWithLogging {} router