support optional fields

This commit is contained in:
Alexander Foremny
2024-06-06 22:42:44 +02:00
parent 612da78d17
commit b1a4822d59
4 changed files with 37 additions and 10 deletions

View File

@@ -1,5 +1,5 @@
module Form.Input module Form.Input
( string, ( input,
) )
where where
@@ -8,8 +8,8 @@ import Form.Internal
import Miso import Miso
import Miso.String (fromMisoString, toMisoString) import Miso.String (fromMisoString, toMisoString)
string :: String -> Form T.Text T.Text input :: String -> Form T.Text T.Text
string label = input label =
Form Form
{ view = \i -> { view = \i ->
[ div_ [] $ [ div_ [] $

View File

@@ -2,9 +2,11 @@ module Form.Internal
( Form (..), ( Form (..),
mapValues, mapValues,
runForm, runForm,
optional,
) )
where where
import Data.Text qualified as T
import Miso import Miso
data Form i o = Form data Form i o = Form
@@ -57,3 +59,16 @@ runForm form i =
form_ [onSubmit (either (\_ -> Left i) (Right) (form.fill i))] $ form_ [onSubmit (either (\_ -> Left i) (Right) (form.fill i))] $
(fmap Left <$> form.view i) (fmap Left <$> form.view i)
<> [button_ [type_ "submit"] [text "submit"]] <> [button_ [type_ "submit"] [text "submit"]]
class IsEmpty i where
isEmpty :: i -> Bool
instance IsEmpty T.Text where
isEmpty = T.null . T.strip
optional :: (IsEmpty i) => Form i o -> Form i (Maybe o)
optional form =
Form
{ view = \i -> form.view i,
fill = \i -> if isEmpty i then Right Nothing else Just <$> form.fill i
}

View File

@@ -10,6 +10,7 @@ where
import Api import Api
import Data.Aeson qualified as A import Data.Aeson qualified as A
import Data.Aeson.KeyMap qualified as AM import Data.Aeson.KeyMap qualified as AM
import Data.ByteString.Lazy.UTF8 as LB
import Data.Maybe import Data.Maybe
import Form qualified as F import Form qualified as F
import Miso import Miso
@@ -52,7 +53,8 @@ viewModel m = do
let input = (fromMaybe (A.Object AM.empty) m.input) let input = (fromMaybe (A.Object AM.empty) m.input)
div_ [] $ div_ [] $
[ viewForm input m.schema, [ viewForm input m.schema,
viewInput input viewInput input,
viewOutput input m.schema
] ]
viewForm :: A.Value -> Schema -> View Action viewForm :: A.Value -> Schema -> View Action
@@ -64,3 +66,13 @@ viewForm input =
viewInput :: A.Value -> View Action viewInput :: A.Value -> View Action
viewInput input = viewInput input =
pre_ [] [text (toMisoString (A.encode input))] pre_ [] [text (toMisoString (A.encode input))]
viewOutput :: A.Value -> Schema -> View Action
viewOutput input schema =
pre_ [] $
[ text $
toMisoString
( either ("Left " <>) (("Right " <>) . LB.toString) $
(A.encode <$> ((schemaForm schema).fill input))
)
]

View File

@@ -115,12 +115,15 @@ schemaForm schema =
"string" -> "string" ->
A.Object . AM.singleton k A.Object . AM.singleton k
<$> ( F.mapValues (getO k) (setO k) $ <$> ( F.mapValues (getO k) (setO k) $
jsonString (AK.toString k) fmap A.String . F.mapValues fromJson toJson $
F.input (AK.toString k)
) )
"string?" -> "string?" ->
A.Object . AM.singleton k A.Object . AM.singleton k
<$> ( F.mapValues (getO k) (setO k) $ <$> ( F.mapValues (getO k) (setO k)
jsonString (AK.toString k) $ fmap (maybe A.Null A.String)
. F.mapValues fromJson toJson
$ F.optional (F.input (AK.toString k))
) )
) )
<$> (M.toList properties) <$> (M.toList properties)
@@ -143,6 +146,3 @@ getO k (A.Object kvs) = fromMaybe A.Null (AM.lookup k kvs)
setO :: AK.Key -> A.Value -> A.Value -> A.Value setO :: AK.Key -> A.Value -> A.Value -> A.Value
setO k v (A.Object kvs) = A.Object (AM.insert k v kvs) setO k v (A.Object kvs) = A.Object (AM.insert k v kvs)
jsonString :: String -> F.Form A.Value A.Value
jsonString = fmap A.String . F.mapValues fromJson toJson . F.string