diff options
Diffstat (limited to 'frontend/app/Form')
-rw-r--r-- | frontend/app/Form/Input.hs | 72 |
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 |