{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
module Ditto.Lucid.Named where
import Data.Foldable (traverse_, fold)
import Data.List.NonEmpty
import Data.Text (Text)
import Ditto.Backend
import Ditto.Core
import Ditto.Generalized.Named as G
import Ditto.Types
import Lucid
import Web.PathPieces
import qualified Data.Text as T
foldTraverse_ :: (Foldable t, Applicative f, Monoid (f b)) => (a -> t (f b)) -> t a -> f ()
foldTraverse_ f = traverse_ (fold . f)
inputText
:: (Environment m input, FormError input err, PathPiece text, Applicative f)
=> (input -> Either err text)
-> Text
-> text
-> Form m input err (HtmlT f ()) text
inputText getInput name initialValue = G.input name getInput inputField initialValue
where
inputField i a = input_ [type_ "text", id_ (encodeFormId i), name_ (encodeFormId i), value_ (toPathPiece a)]
inputMaybeText
:: (Environment m input, FormError input err, PathPiece text, Applicative f)
=> (input -> Either err text)
-> Text
-> Maybe text
-> Form m input err (HtmlT f ()) (Maybe text)
inputMaybeText getInput name initialValue = G.inputMaybe name getInput inputField initialValue
where
inputField i a = let attrs = maybe [] (pure . value_ . toPathPiece) a in
input_ $ type_ "text" : id_ (encodeFormId i) : name_ (encodeFormId i) : attrs
inputPassword
:: (Environment m input, FormError input err, PathPiece text, Applicative f)
=> (input -> Either err text)
-> Text
-> text
-> Form m input err (HtmlT f ()) text
inputPassword getInput name initialValue = G.input name getInput inputField initialValue
where
inputField i a = input_ [type_ "password", id_ (encodeFormId i), name_ (encodeFormId i), value_ (toPathPiece a)]
inputSubmit
:: (Environment m input, FormError input err, PathPiece text, Applicative f)
=> (input -> Either err text)
-> Text
-> text
-> Form m input err (HtmlT f ()) (Maybe text)
inputSubmit getInput name initialValue = G.inputMaybe name getInput inputField (Just initialValue)
where
inputField i a = input_ [type_ "submit", id_ (encodeFormId i), name_ (encodeFormId i), value_ (toPathPiece a)]
inputReset
:: (Environment m input, FormError input err, PathPiece text, Applicative f)
=> Text
-> text
-> Form m input err (HtmlT f ()) ()
inputReset name lbl = G.inputNoData name inputField
where
inputField i = input_ [type_ "submit", id_ (encodeFormId i), name_ (encodeFormId i), value_ (toPathPiece lbl)]
inputHidden
:: (Environment m input, FormError input err, PathPiece text, Applicative f)
=> (input -> Either err text)
-> Text
-> text
-> Form m input err (HtmlT f ()) text
inputHidden getInput name initialValue = G.input name getInput inputField initialValue
where
inputField i a = input_ [type_ "hidden", id_ (encodeFormId i), name_ (encodeFormId i), value_ (toPathPiece a)]
inputButton
:: (Environment m input, FormError input err, PathPiece text, Applicative f)
=> Text
-> text
-> Form m input err (HtmlT f ()) ()
inputButton name lbl = G.inputNoData name inputField
where
inputField i = input_ [type_ "button", id_ (encodeFormId i), name_ (encodeFormId i), value_ (toPathPiece lbl)]
textarea
:: (Environment m input, FormError input err, ToHtml text, Monad f)
=> (input -> Either err text)
-> Int
-> Int
-> Text
-> text
-> Form m input err (HtmlT f ()) text
textarea getInput cols rows name initialValue = G.input name getInput textareaView initialValue
where
textareaView i txt =
textarea_
[ rows_ (toPathPiece rows)
, cols_ (toPathPiece cols)
, id_ (encodeFormId i)
, name_ (encodeFormId i)
] $
toHtml txt
inputFile
:: (Environment m input, FormError input err, FormInput input, Applicative f, ft ~ FileType input, Monoid ft)
=> Text
-> Form m input err (HtmlT f ()) (FileType input)
inputFile name = G.inputFile name fileView
where
fileView i = input_ [type_ "file", id_ (encodeFormId i), name_ (encodeFormId i)]
buttonSubmit
:: (Environment m input, FormError input err, PathPiece text, ToHtml children, Monad f)
=> (input -> Either err text)
-> Text
-> text
-> children
-> Form m input err (HtmlT f ()) (Maybe text)
buttonSubmit getInput name text c = G.inputMaybe name getInput inputField (Just text)
where
inputField i a = button_ [type_ "submit", id_ (encodeFormId i), name_ (encodeFormId i), value_ (toPathPiece a)] $ toHtml c
buttonReset
:: (Environment m input, FormError input err, Monad f)
=> Text
-> HtmlT f ()
-> Form m input err (HtmlT f ()) ()
buttonReset name c = G.inputNoData name inputField
where
inputField i = button_ [type_ "reset", id_ (encodeFormId i), name_ (encodeFormId i)] c
button
:: (Environment m input, FormError input err, Monad f)
=> Text
-> HtmlT f ()
-> Form m input err (HtmlT f ()) ()
button name c = G.inputNoData name inputField
where
inputField i = button_ [type_ "button", id_ (encodeFormId i), name_ (encodeFormId i)] c
label
:: (Environment m input, Monad f)
=> HtmlT f ()
-> Text
-> Form m input err (HtmlT f ()) ()
label c name = G.label name mkLabel
where
mkLabel i = label_ [for_ (encodeFormId i)] c
arbitraryHtml :: Environment m input => view -> Form m input err view ()
arbitraryHtml = view
inputInt
:: (Environment m input, FormError input err, Applicative f)
=> (input -> Either err Int)
-> Text
-> Int
-> Form m input err (HtmlT f ()) Int
inputInt getInput name initialValue = G.input name getInput inputField initialValue
where
inputField i a =
input_
[ type_ "number"
, id_ (encodeFormId i)
, name_ (encodeFormId i)
, value_ (toPathPiece a)
]
inputDouble
:: (Environment m input, FormError input err, Applicative f)
=> (input -> Either err Double)
-> Text
-> Double
-> Form m input err (HtmlT f ()) Double
inputDouble getInput name initialValue = G.input name getInput inputField initialValue
where
inputField i a = input_ [type_ "number", step_ "any", id_ (encodeFormId i), name_ (encodeFormId i), value_ (T.pack $ show a)]
inputCheckbox
:: forall err input m f. (Environment m input, FormError input err, Applicative f)
=> Bool
-> Text
-> Form m input err (HtmlT f ()) Bool
inputCheckbox initiallyChecked name =
Form (successDecode True) (pure initiallyChecked) $ do
i <- getNamedFormId name
v <- getFormInput' i
case v of
Default -> mkCheckbox i initiallyChecked
Missing -> mkCheckbox i False
Found _ -> mkCheckbox i True
where
mkCheckbox i checked =
let checkbox =
input_ $
(if checked then (:) checked_ else id)
[type_ "checkbox", id_ (encodeFormId i), name_ (encodeFormId i), value_ (encodeFormId i)]
in pure
( View $ const $ checkbox
, Ok
( Proved
{ pos = unitRange i
, unProved = if checked then True else False
}
)
)
inputCheckboxes
:: (Functor m, Environment m input, FormError input err, FormInput input, ToHtml lbl, Monad f, PathPiece a, Eq a)
=> Text
-> [(a, lbl)]
-> (input -> Either err [a])
-> (a -> Bool)
-> Form m input err (HtmlT f ()) [a]
inputCheckboxes name choices fromInput isChecked = G.inputMulti name choices fromInput mkCheckboxes isChecked
where
mkCheckboxes nm choices' = foldTraverse_ (mkCheckbox nm) choices'
mkCheckbox nm (Choice i lbl checked val) =
[ input_ $
( (if checked then (checked_ :) else id)
[type_ "checkbox", id_ (encodeFormId i), name_ (encodeFormId nm), value_ (toPathPiece val)]
)
, label_ [for_ (encodeFormId i)] $ toHtml lbl
]
inputRadio
:: (Functor m, Environment m input, FormError input err, FormInput input, Monad f, PathPiece a, Eq a)
=> Text
-> NonEmpty (a, Html ())
-> (input -> Either err a)
-> (a -> Bool)
-> Form m input err (HtmlT f ()) a
inputRadio name choices fromInput isDefault =
G.inputChoice name isDefault choices fromInput mkRadios
where
mkRadios nm choices' = foldTraverse_ (mkRadio nm) choices'
mkRadio nm (Choice i lbl checked val) =
[ input_ $
(if checked then (checked_ :) else id)
[type_ "radio", id_ (encodeFormId i), name_ (encodeFormId nm), value_ (toPathPiece val)]
, label_ [for_ (encodeFormId i)] $ toHtml lbl
, br_ []
]
select
:: (Functor m, Environment m input, FormError input err, FormInput input, Monad f, PathPiece a, Eq a)
=> Text
-> NonEmpty (a, Html ())
-> (input -> Either err a)
-> (a -> Bool)
-> Form m input err (HtmlT f ()) a
select name choices fromInput isDefault = G.inputChoice name isDefault choices fromInput mkSelect
where
mkSelect :: (ToHtml lbl, Monad f, PathPiece a) => FormId -> [Choice lbl a] -> HtmlT f ()
mkSelect nm choices' =
select_ [name_ (encodeFormId nm)] $
traverse_ mkOption choices'
mkOption :: (ToHtml lbl, Monad f, PathPiece a) => Choice lbl a -> HtmlT f ()
mkOption (Choice _ lbl selected val) =
option_
( (if selected then ((:) (selected_ "selected")) else id)
[value_ (toPathPiece val)]
)
(toHtml lbl)
selectMultiple
:: (Functor m, Environment m input, FormError input err, FormInput input, Monad f, PathPiece a, Eq a)
=> Text
-> [(a, Html ())]
-> (input -> Either err [a])
-> (a -> Bool)
-> Form m input err (HtmlT f ()) [a]
selectMultiple name choices fromInput isSelected = G.inputMulti name choices fromInput mkSelect isSelected
where
mkSelect :: (ToHtml lbl, Monad f, PathPiece a) => FormId -> [Choice lbl a] -> HtmlT f ()
mkSelect nm choices' =
select_ [name_ (encodeFormId nm), multiple_ "multiple"] $
traverse_ mkOption choices'
mkOption :: (ToHtml lbl, Monad f, PathPiece a) => Choice lbl a -> HtmlT f ()
mkOption (Choice _ lbl selected val) =
option_
( (if selected then ((:) (selected_ "selected")) else id)
[value_ (toPathPiece val)]
)
(toHtml lbl)