diff options
Diffstat (limited to 'ws2015/ffp/blaetter/11/FFP_U11-3_Yesod.hs')
-rw-r--r-- | ws2015/ffp/blaetter/11/FFP_U11-3_Yesod.hs | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/ws2015/ffp/blaetter/11/FFP_U11-3_Yesod.hs b/ws2015/ffp/blaetter/11/FFP_U11-3_Yesod.hs new file mode 100644 index 0000000..badd9e0 --- /dev/null +++ b/ws2015/ffp/blaetter/11/FFP_U11-3_Yesod.hs | |||
@@ -0,0 +1,145 @@ | |||
1 | -- Fortgeschrittene Funktionale Programmierung, | ||
2 | -- LMU, TCS, Wintersemester 2015/16 | ||
3 | -- Steffen Jost, Alexander Isenko | ||
4 | -- | ||
5 | -- Übungsblatt 11. 13.01.2016 | ||
6 | -- | ||
7 | -- Teilaufgabe | ||
8 | -- A11-3 Yesod: Applikative Formulare | ||
9 | -- | ||
10 | -- Betrachten Sie das Beispiel aus der Vorlesung zu applikativen Formularen. | ||
11 | -- Der Code ist hier vollständig enthalten und sollte problemlos ausführbar sein. | ||
12 | |||
13 | -- a) | ||
14 | -- Erweiteren Sie diese Webapplikation um eine Seite, auf der ein Benutzer | ||
15 | -- mit einem Formular zur Eingabe einer positiven ganzen Zahl auffordert. | ||
16 | -- Der Benutzer wird ggf. solange erneut aufgefordert, bis eine positive ganze Zahl ermittelt wurde; | ||
17 | -- danach wird die Zahl einfach auf dem Bildschirm ausgegeben. | ||
18 | |||
19 | |||
20 | |||
21 | -- b) | ||
22 | -- Erweitern Sie Ihr Programm aus der vorherigen Teilausgabe, so dass | ||
23 | -- je nach der eingegebenen Zahl ein Formular zur Eingabe dieser Anzahl | ||
24 | -- an Autos (gemäß dem Beispiel) abgefragt werden. | ||
25 | -- | ||
26 | -- Nutzen Sie dazu die Möglichkeit zur Kombination mehrerer Formulare in Yesod! | ||
27 | -- Auch für 5 Autos soll nur ein einziges Formular mit einem einzelnen Absenden-Knopf | ||
28 | -- angzeigt werden, welches entsprechend viele Felder für 5 Autos enthält. | ||
29 | -- | ||
30 | -- Nach dem Absenden des Formulares, sollen die eingegebenen Autos einfach nur | ||
31 | -- auf dem Bildschrim dargestellt werden. | ||
32 | -- | ||
33 | -- Ein Beispiel zur Kombination zweier Formulare zu einem einzigen Formular: | ||
34 | -- | ||
35 | -- twoCarAForm :: AForm Handler (Car,Car) | ||
36 | -- twoCarAForm = (,) <$> carAForm <*> carAForm | ||
37 | -- | ||
38 | |||
39 | |||
40 | {-# LANGUAGE GADTs #-} | ||
41 | {-# LANGUAGE ViewPatterns #-} | ||
42 | {-# LANGUAGE MultiParamTypeClasses #-} | ||
43 | {-# LANGUAGE OverloadedStrings #-} | ||
44 | {-# LANGUAGE TypeFamilies #-} | ||
45 | {-# LANGUAGE TemplateHaskell, QuasiQuotes #-} | ||
46 | |||
47 | |||
48 | import Yesod | ||
49 | import Data.Text | ||
50 | import Control.Applicative | ||
51 | import Yesod.Form | ||
52 | |||
53 | |||
54 | {- LÖSUNGSVORSCHLAG -} | ||
55 | |||
56 | main :: IO () | ||
57 | main = warp 3000 CarApp | ||
58 | |||
59 | |||
60 | data CarApp = CarApp | ||
61 | |||
62 | instance Yesod CarApp | ||
63 | |||
64 | instance RenderMessage CarApp FormMessage where | ||
65 | renderMessage _ _ = defaultFormMessage | ||
66 | |||
67 | mkYesod "CarApp" [parseRoutes| | ||
68 | / HomeR | ||
69 | /car/#Int CarR | ||
70 | |] | ||
71 | |||
72 | |||
73 | |||
74 | data Car = Car { carModel :: Text | ||
75 | , carYear :: Int | ||
76 | , carColor :: Maybe Text | ||
77 | } | ||
78 | deriving Show | ||
79 | |||
80 | carAForm :: AForm Handler Car | ||
81 | carAForm = Car | ||
82 | <$> areq textField "Model" Nothing | ||
83 | <*> areq intField "Year" (Just 1996) | ||
84 | <*> aopt textField "Color" Nothing | ||
85 | |||
86 | carForm :: Html -> MForm Handler (FormResult Car, Widget) | ||
87 | carForm = renderBootstrap2 carAForm | ||
88 | |||
89 | -- Beispiel zur Kombination zweier applikativer Formulare zu einem: | ||
90 | twoCarAForm :: AForm Handler (Car,Car) | ||
91 | twoCarAForm = (,) <$> carAForm <*> carAForm | ||
92 | |||
93 | |||
94 | handleHomeR :: Handler Html | ||
95 | handleHomeR = redirect $ CarR 3 | ||
96 | |||
97 | |||
98 | handleCarR :: Int -> Handler Html | ||
99 | handleCarR n = do | ||
100 | ((result,widget), enctype) <- runFormPost $ carForm | ||
101 | case result of | ||
102 | FormMissing -> defaultLayout $ do | ||
103 | setTitle "Form Demo" | ||
104 | [whamlet| | ||
105 | <h2>Form Demo | ||
106 | <form method=post action=@{CarR n} enctype=#{enctype}> | ||
107 | ^{widget} | ||
108 | <button>Submit | ||
109 | |] | ||
110 | |||
111 | FormSuccess car -> defaultLayout $ do | ||
112 | setTitle "Form Auswerten" | ||
113 | [whamlet| | ||
114 | <h2>#{n} Cars should have been received: | ||
115 | <ul> | ||
116 | $forall acar <- [car] | ||
117 | <li>#{show acar} | ||
118 | <p> | ||
119 | <a href=@{HomeR}>Zurück | ||
120 | |] | ||
121 | |||
122 | _ -> defaultLayout [whamlet| | ||
123 | <h2>Fehler! | ||
124 | <p>Bitte nochmal eingeben: | ||
125 | <form method=post action=@{CarR n} enctype=#{enctype}> | ||
126 | ^{widget} | ||
127 | <button>Abschicken | ||
128 | |] | ||
129 | -- das gemeinsame hamlet-widget bei | ||
130 | -- FormMissing und FormFailure text | ||
131 | -- kann man natürlich auch nur einmal | ||
132 | -- in einer lokalen Variable definieren | ||
133 | |||
134 | |||
135 | |||
136 | |||
137 | |||
138 | |||
139 | -- | ||
140 | -- Weiter geht es mit der Datei FFP_U11-4_TemplateHaskell.hs | ||
141 | -- | ||
142 | |||
143 | |||
144 | |||
145 | |||