aboutsummaryrefslogtreecommitdiffstats
path: root/frontend/app/Form/Input.hs
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/app/Form/Input.hs')
-rw-r--r--frontend/app/Form/Input.hs72
1 files changed, 72 insertions, 0 deletions
diff --git a/frontend/app/Form/Input.hs b/frontend/app/Form/Input.hs
index 7619326..67a6d80 100644
--- a/frontend/app/Form/Input.hs
+++ b/frontend/app/Form/Input.hs
@@ -1,13 +1,85 @@
module Form.Input
( inputText,
inputNumber,
+ inputUnion,
+ TypeName(..),
+ Type(..)
)
where
+import Control.Applicative
+import Control.Arrow (first, second)
+import Data.Map qualified as M
import Form.Internal
import Miso
import Miso.String (MisoString, fromMisoString, null, strip, toMisoString)
+data TypeName = StringType | NumberType
+ deriving (Eq, Ord)
+
+data Type = IsNumber Double | IsString MisoString
+
+inputUnion :: MisoString -> [TypeName] -> Form (TypeName, M.Map TypeName MisoString) (Maybe Type)
+inputUnion label types =
+ foldl1 (<|>)
+ <$> mapM
+ ( \case
+ StringType ->
+ mapValues
+ ( \(selectedType, typeInputs) ->
+ ( selectedType == StringType,
+ M.findWithDefault "" StringType typeInputs
+ )
+ )
+ ( \(checked, inputString) (selectedType, typeInputs) ->
+ ( if checked then StringType else selectedType,
+ M.insert StringType inputString typeInputs
+ )
+ )
+ $ fmap (fmap IsString)
+ $ withRadio
+ $ inputText label
+ NumberType ->
+ mapValues
+ ( \(selectedType, typeInputs) ->
+ ( selectedType == NumberType,
+ M.findWithDefault "" NumberType typeInputs
+ )
+ )
+ ( \(checked, inputString) (selectedType, typeInputs) ->
+ ( if checked then NumberType else selectedType,
+ M.insert NumberType inputString typeInputs
+ )
+ )
+ $ fmap (fmap IsNumber)
+ $ withRadio
+ $ inputNumber label
+ )
+ types
+
+radio :: Form Bool Bool
+radio =
+ Form
+ { view = \checked ->
+ [ div_ [] $
+ [ input_
+ [ type_ "radio",
+ checked_ checked,
+ onClick (not checked)
+ ]
+ ]
+ ],
+ fill = Right
+ }
+
+withRadio :: Form i o -> Form (Bool, i) (Maybe o)
+withRadio form =
+ (\(checked, x) -> if checked then Just x else Nothing)
+ <$> liftA2
+ (,)
+ (mapValues fst (first . const) radio)
+ (mapValues snd (second . const) form)
+
inputNumber :: MisoString -> Form MisoString Double
inputNumber label =
let parse :: MisoString -> Either MisoString Double