summaryrefslogtreecommitdiff
path: root/Handler
diff options
context:
space:
mode:
authorGregor Kleen <gkleen@yggdrasil.li>2017-03-15 18:11:47 +0100
committerGregor Kleen <gkleen@yggdrasil.li>2017-03-15 18:11:47 +0100
commit3cd4169e33c07b71129aafcecfb81a3b5007fa39 (patch)
tree261de0303273cc1a861977dc9aebce235d0afe51 /Handler
parent37f0dac79707a0de81ec6364d2704007eefd9289 (diff)
downloadbar-3cd4169e33c07b71129aafcecfb81a3b5007fa39.tar
bar-3cd4169e33c07b71129aafcecfb81a3b5007fa39.tar.gz
bar-3cd4169e33c07b71129aafcecfb81a3b5007fa39.tar.bz2
bar-3cd4169e33c07b71129aafcecfb81a3b5007fa39.tar.xz
bar-3cd4169e33c07b71129aafcecfb81a3b5007fa39.zip
Autocomplete types
Diffstat (limited to 'Handler')
-rw-r--r--Handler/Common.hs126
-rw-r--r--Handler/Types.hs15
2 files changed, 91 insertions, 50 deletions
diff --git a/Handler/Common.hs b/Handler/Common.hs
index 65988da..a1ae34b 100644
--- a/Handler/Common.hs
+++ b/Handler/Common.hs
@@ -26,6 +26,8 @@ import Control.Lens
26 26
27import Handler.Common.Types 27import Handler.Common.Types
28 28
29import Text.Julius (RawJS(..))
30
29dayFormat :: Day -> String 31dayFormat :: Day -> String
30dayFormat = formatTime defaultTimeLocale "%e. %b %y" 32dayFormat = formatTime defaultTimeLocale "%e. %b %y"
31 33
@@ -36,8 +38,12 @@ itemForm proto identView = do
36 38
37 t <- lift . runDB $ maybe (return Nothing) (fmap (Just . kindType) . getType) proto 39 t <- lift . runDB $ maybe (return Nothing) (fmap (Just . kindType) . getType) proto
38 40
39 (kindRes, kindWidget) <- kindField $ itemKind <$> proto 41 let kt kWidget tWidget =
40 (typeRes, typeWidget) <- typeField $ t 42 [whamlet|
43 <div .td>^{kWidget}
44 <div .td>^{tWidget}
45 |]
46 ((kindRes, typeRes), typedKindWidget) <- typedKindField kt ((itemKind <$> proto), t)
41 (boughtRes, boughtWidget) <- dayForm (maybe (Just $ Just today) Just $ fmap itemBought proto) "Unknown" 47 (boughtRes, boughtWidget) <- dayForm (maybe (Just $ Just today) Just $ fmap itemBought proto) "Unknown"
42 (expiresRes, expiresWidget) <- dayForm (fmap itemExpires proto) "Never" 48 (expiresRes, expiresWidget) <- dayForm (fmap itemExpires proto) "Never"
43 (openedRes, openedWidget) <- dayForm (fmap itemOpened proto) "Never" 49 (openedRes, openedWidget) <- dayForm (fmap itemOpened proto) "Never"
@@ -54,8 +60,7 @@ itemForm proto identView = do
54 [whamlet| 60 [whamlet|
55 $newline never 61 $newline never
56 #{identView} 62 #{identView}
57 <div .td>^{kindWidget} 63 ^{typedKindWidget}
58 <div .td>^{typeWidget}
59 <div .td>^{boughtWidget} 64 <div .td>^{boughtWidget}
60 <div .td>^{expiresWidget} 65 <div .td>^{expiresWidget}
61 <div .td>^{openedWidget} 66 <div .td>^{openedWidget}
@@ -93,9 +98,14 @@ referenceForm :: Maybe Reference -- ^ Update existing item or insert new?
93 -> Html -> MForm Handler (FormResult (WithType Reference), Widget) 98 -> Html -> MForm Handler (FormResult (WithType Reference), Widget)
94referenceForm proto identView = do 99referenceForm proto identView = do
95 t <- lift . runDB $ maybe (return Nothing) (fmap (Just . kindType) . getType) proto 100 t <- lift . runDB $ maybe (return Nothing) (fmap (Just . kindType) . getType) proto
101
102 let kt kWidget tWidget =
103 [whamlet|
104 <div .td>^{kWidget}
105 <div .td>^{tWidget}
106 |]
96 107
97 (kindRes, kindWidget) <- kindField $ referenceKind <$> proto 108 ((kindRes, typeRes), typedKindWidget) <- typedKindField kt ((referenceKind <$> proto), t)
98 (typeRes, typeWidget) <- typeField $ t
99 109
100 let referenceRes = do 110 let referenceRes = do
101 referenceKind <- kindRes 111 referenceKind <- kindRes
@@ -106,63 +116,79 @@ referenceForm proto identView = do
106 [whamlet| 116 [whamlet|
107 $newline never 117 $newline never
108 #{identView} 118 #{identView}
109 <div .td>^{kindWidget} 119 ^{typedKindWidget}
110 <div .td>^{typeWidget}
111 |] 120 |]
112 121
113referenceListing :: ReferenceState -> Widget 122referenceListing :: ReferenceState -> Widget
114referenceListing ReferenceState{ refFormState = formState, ..} = $(widgetFile "referenceListing") 123referenceListing ReferenceState{ refFormState = formState, ..} = $(widgetFile "referenceListing")
115 124
116kindField :: Maybe Text -> MForm Handler (FormResult Text, Widget) 125typedKindField :: (Widget -> Widget -> Widget) -- ^ `\kindWidget typeWidget -> _`
117kindField proto = do 126 -> (Maybe Text, Maybe Text) -- ^ `(kindProto, typeProto)`
118 optionId <- ("options" <>) . tshow . hashUnique <$> liftIO newUnique 127 -> MForm Handler ((FormResult Text, FormResult Text), Widget) -- ^ `((kindRes, typeRes), typedKindWidget)`
119 128typedKindField collate (kindProto, typeProto) = do
129 tOptionId <- ("options" <>) . tshow . hashUnique <$> liftIO newUnique
120 let 130 let
121 attrs = [ ("list", optionId) 131 tAttrs = [ ("list", tOptionId)
122 , ("autocomplete", "off") 132 , ("autocomplete", "off")
123 ] 133 ]
124 134 kOptionId <- ("options" <>) . tshow . hashUnique <$> liftIO newUnique
125 (kindRes, kindView) <- mreq textField ("" { fsAttrs = attrs }) proto
126
127 options <- lift kinds
128
129 return . (kindRes, ) $
130 [whamlet|
131 $newline never
132 ^{fvInput kindView}
133 <datalist ##{optionId}>
134 $forall opt <- options
135 <option value=#{opt}>
136 |]
137
138typeField :: Maybe Text -> MForm Handler (FormResult Text, Widget)
139typeField proto = do
140 optionId <- ("options" <>) . tshow . hashUnique <$> liftIO newUnique
141 135
142 let 136 let
143 attrs = [ ("list", optionId) 137 kAttrs = [ ("list", kOptionId)
144 , ("autocomplete", "off") 138 , ("autocomplete", "off")
145 ] 139 ]
146 140
147 (typeRes, typeView) <- mreq textField ("" { fsAttrs = attrs }) proto 141 (kindRes, kindView) <- mreq textField ("" { fsAttrs = kAttrs }) kindProto
148 142 (typeRes, typeView) <- mreq textField ("" { fsAttrs = tAttrs }) typeProto
149 (Set.fromList . map (kindType . entityVal) -> options) <- lift . runDB $ selectList [] [] 143
150 144 kOptions <- lift kinds
151 return . (typeRes, ) $ 145 (Set.fromList . map (kindType . entityVal) -> tOptions) <- lift . runDB $ selectList [] []
152 [whamlet| 146
153 $newline never 147 return . ((kindRes, typeRes), ) $ do
154 ^{fvInput typeView} 148 toWidget $
155 <datalist ##{optionId}> 149 [julius|
156 $forall opt <- Set.toList options 150 $(function () {
157 <option value=#{opt}> 151 $("##{rawJS $ fvId kindView}").change(function () {
158 |] 152 $.ajax({
153 url: '@{TypeR}',
154 type: 'GET',
155 contentType: 'application/json',
156 data: {
157 kind: $(this).val()
158 },
159 success: function (answer) {
160 $("##{rawJS $ fvId typeView}").val(answer);
161 typeChanged = false;
162 }
163 });
164 }) ;
165 });
166 |]
167 let
168 kindWidget =
169 [whamlet|
170 $newline never
171 ^{fvInput kindView}
172 <datalist ##{kOptionId}>
173 $forall opt <- kOptions
174 <option value=#{opt}>
175 |]
176 typeWidget =
177 [whamlet|
178 $newline never
179 ^{fvInput typeView}
180 <datalist ##{tOptionId}>
181 $forall opt <- tOptions
182 <option value=#{opt}>
183 |]
184 collate kindWidget typeWidget
159 185
160kinds :: Handler [Text] 186kinds :: Handler (Set Text)
161kinds = do 187kinds = do
162 stock <- runDB $ selectList [] [] 188 stock <- runDB $ selectList [] []
163 reference <- runDB $ selectList [] [] 189 reference <- runDB $ selectList [] []
164 190
165 return $ concat 191 return . Set.fromList $ concat
166 [ [ itemKind | Entity _ Item{..} <- stock ] 192 [ [ itemKind | Entity _ Item{..} <- stock ]
167 , [ referenceKind | Entity _ Reference{..} <- reference ] 193 , [ referenceKind | Entity _ Reference{..} <- reference ]
168 ] 194 ]
diff --git a/Handler/Types.hs b/Handler/Types.hs
new file mode 100644
index 0000000..04055ad
--- /dev/null
+++ b/Handler/Types.hs
@@ -0,0 +1,15 @@
1module Handler.Types where
2
3import Import
4
5import Data.Set (Set)
6import qualified Data.Set as Set
7
8getTypesR :: Handler Value
9getTypesR = returnJson <=< runDB $ do
10 Set.fromList . map (kindType . entityVal) <$> selectList [] []
11
12getTypeR :: Handler Value
13getTypeR = do
14 kind <- maybe (invalidArgs ["kind"]) return =<< lookupGetParam "kind"
15 returnJson <=< runDB $ kindType . entityVal <$> getBy404 (UniqueKind $ normalizeKind kind)