Button cleanup

This commit is contained in:
Gregor Kleen 2019-01-31 11:12:20 +01:00
parent 73a19863b1
commit 8684ca016f
11 changed files with 121 additions and 147 deletions

View File

@ -14,15 +14,14 @@ import qualified Data.CaseInsensitive as CI
data DummyMessage = MsgDummyIdent data DummyMessage = MsgDummyIdent
| MsgDummyNoFormData | MsgDummyNoFormData
deriving (Eq, Ord, Enum, Bounded, Read, Show, Generic, Typeable)
dummyForm :: ( RenderMessage site FormMessage dummyForm :: ( RenderMessage site FormMessage
, RenderMessage site DummyMessage , RenderMessage site DummyMessage
, RenderMessage site ButtonMessage
, YesodPersist site , YesodPersist site
, SqlBackendCanRead (YesodPersistBackend site) , SqlBackendCanRead (YesodPersistBackend site)
, Button site SubmitButton , Button site ButtonSubmit
, Show (ButtonCssClass site)
) => AForm (HandlerT site IO) (CI Text) ) => AForm (HandlerT site IO) (CI Text)
dummyForm = areq (selectField userList) (fslI MsgDummyIdent) Nothing dummyForm = areq (selectField userList) (fslI MsgDummyIdent) Nothing
<* submitButton <* submitButton
@ -35,9 +34,7 @@ dummyLogin :: ( YesodAuth site
, SqlBackendCanRead (YesodPersistBackend site) , SqlBackendCanRead (YesodPersistBackend site)
, RenderMessage site FormMessage , RenderMessage site FormMessage
, RenderMessage site DummyMessage , RenderMessage site DummyMessage
, RenderMessage site ButtonMessage , Button site ButtonSubmit
, Button site SubmitButton
, Show (ButtonCssClass site)
) => AuthPlugin site ) => AuthPlugin site
dummyLogin = AuthPlugin{..} dummyLogin = AuthPlugin{..}
where where

View File

@ -28,13 +28,14 @@ import qualified Yesod.Auth.Message as Msg
data CampusLogin = CampusLogin data CampusLogin = CampusLogin
{ campusIdent :: CI Text { campusIdent :: CI Text
, campusPassword :: Text , campusPassword :: Text
} } deriving (Generic, Typeable)
data CampusMessage = MsgCampusIdentNote data CampusMessage = MsgCampusIdentNote
| MsgCampusIdent | MsgCampusIdent
| MsgCampusPassword | MsgCampusPassword
| MsgCampusSubmit | MsgCampusSubmit
| MsgCampusInvalidCredentials | MsgCampusInvalidCredentials
deriving (Eq, Ord, Enum, Bounded, Read, Show, Generic, Typeable)
findUser :: LdapConf -> Ldap -> Text -> [Ldap.Attr] -> IO [Ldap.SearchEntry] findUser :: LdapConf -> Ldap -> Text -> [Ldap.Attr] -> IO [Ldap.SearchEntry]
@ -53,9 +54,7 @@ userPrincipalName = Ldap.Attr "userPrincipalName"
campusForm :: ( RenderMessage site FormMessage campusForm :: ( RenderMessage site FormMessage
, RenderMessage site CampusMessage , RenderMessage site CampusMessage
, RenderMessage site ButtonMessage , Button site ButtonSubmit
, Button site SubmitButton
, Show (ButtonCssClass site)
) => AForm (HandlerT site IO) CampusLogin ) => AForm (HandlerT site IO) CampusLogin
campusForm = CampusLogin campusForm = CampusLogin
<$> areq ciField (fslpI MsgCampusIdent "user.name@campus.lmu.de" & setTooltip MsgCampusIdentNote) Nothing <$> areq ciField (fslpI MsgCampusIdent "user.name@campus.lmu.de" & setTooltip MsgCampusIdentNote) Nothing
@ -66,9 +65,7 @@ campusLogin :: forall site.
( YesodAuth site ( YesodAuth site
, RenderMessage site FormMessage , RenderMessage site FormMessage
, RenderMessage site CampusMessage , RenderMessage site CampusMessage
, RenderMessage site ButtonMessage , Button site ButtonSubmit
, Button site SubmitButton
, Show (ButtonCssClass site)
) => LdapConf -> LdapPool -> AuthPlugin site ) => LdapConf -> LdapPool -> AuthPlugin site
campusLogin conf@LdapConf{..} pool = AuthPlugin{..} campusLogin conf@LdapConf{..} pool = AuthPlugin{..}
where where
@ -116,7 +113,7 @@ data CampusUserException = CampusUserLdapError LdapPoolError
| CampusUserHostCannotConnect String [IOException] | CampusUserHostCannotConnect String [IOException]
| CampusUserNoResult | CampusUserNoResult
| CampusUserAmbiguous | CampusUserAmbiguous
deriving (Show, Eq, Typeable) deriving (Show, Eq, Generic, Typeable)
instance Exception CampusUserException instance Exception CampusUserException

View File

@ -19,17 +19,16 @@ import qualified Yesod.Auth.Message as Msg
data HashLogin = HashLogin data HashLogin = HashLogin
{ hashIdent :: CI Text { hashIdent :: CI Text
, hashPassword :: Text , hashPassword :: Text
} } deriving (Generic, Typeable)
data PWHashMessage = MsgPWHashIdent data PWHashMessage = MsgPWHashIdent
| MsgPWHashPassword | MsgPWHashPassword
deriving (Eq, Ord, Enum, Bounded, Read, Show, Generic, Typeable)
hashForm :: ( RenderMessage site FormMessage hashForm :: ( RenderMessage site FormMessage
, RenderMessage site PWHashMessage , RenderMessage site PWHashMessage
, RenderMessage site ButtonMessage , Button site ButtonSubmit
, Button site SubmitButton
, Show (ButtonCssClass site)
) => AForm (HandlerT site IO) HashLogin ) => AForm (HandlerT site IO) HashLogin
hashForm = HashLogin hashForm = HashLogin
<$> areq ciField (fslpI MsgPWHashIdent "Identifikation") Nothing <$> areq ciField (fslpI MsgPWHashIdent "Identifikation") Nothing
@ -42,9 +41,7 @@ hashLogin :: ( YesodAuth site
, SqlBackendCanRead (YesodPersistBackend site) , SqlBackendCanRead (YesodPersistBackend site)
, RenderMessage site FormMessage , RenderMessage site FormMessage
, RenderMessage site PWHashMessage , RenderMessage site PWHashMessage
, RenderMessage site ButtonMessage , Button site ButtonSubmit
, Button site SubmitButton
, Show (ButtonCssClass site)
) => PWHashAlgorithm -> AuthPlugin site ) => PWHashAlgorithm -> AuthPlugin site
hashLogin pwHashAlgo = AuthPlugin{..} hashLogin pwHashAlgo = AuthPlugin{..}
where where

View File

@ -276,13 +276,28 @@ menuItemAccessCallback MenuItem{..} = and2M ((==) Authorized <$> authCheck) menu
$(return []) $(return [])
data instance ButtonCssClass UniWorX = BCDefault | BCPrimary | BCSuccess | BCInfo | BCWarning | BCDanger | BCLink data instance ButtonClass UniWorX
deriving (Enum, Eq, Ord, Bounded, Read, Show) = BCIsButton
| BCDefault
| BCPrimary
| BCSuccess
| BCInfo
| BCWarning
| BCDanger
| BCLink
deriving (Enum, Eq, Ord, Bounded, Read, Show, Generic, Typeable)
instance Universe (ButtonClass UniWorX)
instance Finite (ButtonClass UniWorX)
instance Button UniWorX SubmitButton where instance PathPiece (ButtonClass UniWorX) where
label BtnSubmit = [whamlet|_{MsgBtnSubmit}|] toPathPiece BCIsButton = "btn"
toPathPiece bClass = ("btn-" <>) . camelToPathPiece' 1 $ tshow bClass
fromPathPiece = finiteFromPathPiece
cssClass BtnSubmit = BCPrimary
embedRenderMessage ''UniWorX ''ButtonSubmit id
instance Button UniWorX ButtonSubmit where
btnClasses BtnSubmit = [BCIsButton, BCPrimary]
getTimeLocale' :: [Lang] -> TimeLocale getTimeLocale' :: [Lang] -> TimeLocale

View File

@ -13,8 +13,6 @@ import Control.Monad.Trans.Except
-- import Data.Function ((&)) -- import Data.Function ((&))
-- import Yesod.Form.Bootstrap3 -- import Yesod.Form.Bootstrap3
import Web.PathPieces (showToPathPiece, readFromPathPiece)
import Database.Persist.Sql (fromSqlKey) import Database.Persist.Sql (fromSqlKey)
-- import Colonnade hiding (fromMaybe) -- import Colonnade hiding (fromMaybe)
@ -23,19 +21,19 @@ import Database.Persist.Sql (fromSqlKey)
-- import qualified Data.UUID.Cryptographic as UUID -- import qualified Data.UUID.Cryptographic as UUID
-- BEGIN - Buttons needed only here -- BEGIN - Buttons needed only here
data CreateButton = CreateMath | CreateInf -- Dummy for Example data ButtonCreate = CreateMath | CreateInf -- Dummy for Example
deriving (Enum, Eq, Ord, Bounded, Read, Show) deriving (Enum, Eq, Ord, Bounded, Read, Show, Generic, Typeable)
instance Universe ButtonCreate
instance Finite ButtonCreate
instance PathPiece CreateButton where -- for displaying the button only, not really for paths nullaryPathPiece ''ButtonCreate camelToPathPiece
toPathPiece = showToPathPiece
fromPathPiece = readFromPathPiece
instance Button UniWorX CreateButton where instance Button UniWorX ButtonCreate where
label CreateMath = [whamlet|Ma<i>thema</i>tik|] btnLabel CreateMath = [whamlet|Ma<i>thema</i>tik|]
label CreateInf = "Informatik" btnLabel CreateInf = "Informatik"
cssClass CreateMath = BCInfo btnClasses CreateMath = [BCIsButton, BCInfo]
cssClass CreateInf = BCPrimary btnClasses CreateInf = [BCIsButton, BCPrimary]
-- END Button needed here -- END Button needed here
emailTestForm :: AForm (HandlerT UniWorX IO) (Email, MailContext) emailTestForm :: AForm (HandlerT UniWorX IO) (Email, MailContext)
@ -60,7 +58,7 @@ emailTestForm = (,)
getAdminTestR, postAdminTestR :: Handler Html -- Demo Page. Referenzimplementierungen sollte hier gezeigt werden! getAdminTestR, postAdminTestR :: Handler Html -- Demo Page. Referenzimplementierungen sollte hier gezeigt werden!
getAdminTestR = postAdminTestR getAdminTestR = postAdminTestR
postAdminTestR = do postAdminTestR = do
((btnResult, btnWdgt), btnEnctype) <- runFormPost $ identifyForm "buttons" (buttonForm :: Form CreateButton) ((btnResult, btnWdgt), btnEnctype) <- runFormPost $ identifyForm "buttons" (buttonForm :: Form ButtonCreate)
case btnResult of case btnResult of
(FormSuccess CreateInf) -> addMessage Info "Informatik-Knopf gedrückt" (FormSuccess CreateInf) -> addMessage Info "Informatik-Knopf gedrückt"
(FormSuccess CreateMath) -> addMessage Warning "Knopf Mathematik erkannt" (FormSuccess CreateMath) -> addMessage Warning "Knopf Mathematik erkannt"

View File

@ -222,7 +222,7 @@ getProfileDataR = do
let tutorialTable = [whamlet|Übungsgruppen werden momentan leider noch nicht unterstützt.|] let tutorialTable = [whamlet|Übungsgruppen werden momentan leider noch nicht unterstützt.|]
-- Delete Button -- Delete Button
(btnWdgt, btnEnctype) <- generateFormPost (buttonForm :: Form BtnDelete) (btnWdgt, btnEnctype) <- generateFormPost (buttonForm :: Form ButtonDelete)
defaultLayout $ do defaultLayout $ do
let delWdgt = $(widgetFile "widgets/data-delete") let delWdgt = $(widgetFile "widgets/data-delete")
$(widgetFile "profileData") $(widgetFile "profileData")

View File

@ -277,15 +277,15 @@ getSheetListR tid ssh csh = do
$(widgetFile "sheetList") $(widgetFile "sheetList")
data ButtonGeneratePseudonym = BtnGenerate data ButtonGeneratePseudonym = BtnGenerate
deriving (Enum, Eq, Ord, Bounded, Read, Show) deriving (Enum, Eq, Ord, Bounded, Read, Show, Generic, Typeable)
instance Universe ButtonGeneratePseudonym instance Universe ButtonGeneratePseudonym
instance Finite ButtonGeneratePseudonym instance Finite ButtonGeneratePseudonym
nullaryPathPiece ''ButtonGeneratePseudonym (camelToPathPiece' 1) nullaryPathPiece ''ButtonGeneratePseudonym (camelToPathPiece' 1)
instance Button UniWorX ButtonGeneratePseudonym where instance Button UniWorX ButtonGeneratePseudonym where
label BtnGenerate = [whamlet|_{MsgSheetGeneratePseudonym}|] btnLabel BtnGenerate = [whamlet|_{MsgSheetGeneratePseudonym}|]
cssClass BtnGenerate = BCDefault btnClasses BtnGenerate = [BCIsButton, BCDefault]
-- Show single sheet -- Show single sheet
getSShowR :: TermId -> SchoolId -> CourseShorthand -> SheetName -> Handler Html getSShowR :: TermId -> SchoolId -> CourseShorthand -> SheetName -> Handler Html

View File

@ -15,8 +15,6 @@ import qualified Data.Char as Char
import qualified Data.CaseInsensitive as CI import qualified Data.CaseInsensitive as CI
import qualified Data.Foldable as Foldable
-- import Yesod.Core -- import Yesod.Core
import qualified Data.Text as T import qualified Data.Text as T
-- import Yesod.Form.Types -- import Yesod.Form.Types
@ -51,64 +49,55 @@ import Data.Aeson.Text (encodeToLazyText)
-- Buttons (new version ) -- -- Buttons (new version ) --
---------------------------- ----------------------------
data BtnDelete = BtnDelete data ButtonDelete = BtnDelete
deriving (Enum, Eq, Ord, Bounded, Read, Show) deriving (Enum, Eq, Ord, Bounded, Read, Show, Generic, Typeable)
instance Universe ButtonDelete
instance Finite ButtonDelete
instance Universe BtnDelete nullaryPathPiece ''ButtonDelete $ camelToPathPiece' 1
instance Finite BtnDelete
nullaryPathPiece ''BtnDelete $ camelToPathPiece' 1 embedRenderMessage ''UniWorX ''ButtonDelete id
instance Button UniWorX ButtonDelete where
btnClasses BtnDelete = [BCIsButton, BCDanger]
instance Button UniWorX BtnDelete where data ButtonRegister = BtnRegister | BtnDeregister
label BtnDelete = [whamlet|_{MsgBtnDelete}|] deriving (Enum, Eq, Ord, Bounded, Read, Show, Generic, Typeable)
instance Universe ButtonRegister
instance Finite ButtonRegister
cssClass BtnDelete = BCDanger nullaryPathPiece ''ButtonRegister $ camelToPathPiece' 1
data RegisterButton = BtnRegister | BtnDeregister embedRenderMessage ''UniWorX ''ButtonRegister id
deriving (Enum, Eq, Ord, Bounded, Read, Show) instance Button UniWorX ButtonRegister where
btnClasses BtnRegister = [BCIsButton, BCPrimary]
btnClasses BtnDeregister = [BCIsButton, BCDanger]
instance Universe RegisterButton data ButtonHijack = BtnHijack
instance Finite RegisterButton deriving (Enum, Eq, Ord, Bounded, Read, Show, Generic, Typeable)
instance Universe ButtonHijack
instance Finite ButtonHijack
nullaryPathPiece ''RegisterButton $ camelToPathPiece' 1 nullaryPathPiece ''ButtonHijack $ camelToPathPiece' 1
instance Button UniWorX RegisterButton where embedRenderMessage ''UniWorX ''ButtonHijack id
label BtnRegister = [whamlet|_{MsgBtnRegister}|] instance Button UniWorX ButtonHijack where
label BtnDeregister = [whamlet|_{MsgBtnDeregister}|] btnClasses BtnHijack = [BCIsButton, BCDefault]
cssClass BtnRegister = BCPrimary data ButtonSubmitDelete = BtnSubmit' | BtnDelete'
cssClass BtnDeregister = BCDanger deriving (Enum, Eq, Ord, Bounded, Read, Show, Generic, Typeable)
data AdminHijackUserButton = BtnHijack instance Universe ButtonSubmitDelete
deriving (Enum, Eq, Ord, Bounded, Read, Show) instance Finite ButtonSubmitDelete
instance Universe AdminHijackUserButton embedRenderMessage ''UniWorX ''ButtonSubmitDelete $ dropSuffix "'"
instance Finite AdminHijackUserButton instance Button UniWorX ButtonSubmitDelete where
btnClasses BtnSubmit' = [BCIsButton, BCPrimary]
nullaryPathPiece ''AdminHijackUserButton $ camelToPathPiece' 1 btnClasses BtnDelete' = [BCIsButton, BCDanger]
instance Button UniWorX AdminHijackUserButton where
label BtnHijack = [whamlet|_{MsgBtnHijack}|]
cssClass BtnHijack = BCDefault
data BtnSubmitDelete = BtnSubmit' | BtnDelete'
deriving (Enum, Eq, Ord, Bounded, Read, Show)
instance Universe BtnSubmitDelete
instance Finite BtnSubmitDelete
instance Button UniWorX BtnSubmitDelete where
label BtnSubmit' = [whamlet|_{MsgBtnSubmit}|]
label BtnDelete' = [whamlet|_{MsgBtnDelete}|]
cssClass BtnSubmit' = BCPrimary
cssClass BtnDelete' = BCDanger
btnValidate _ BtnSubmit' = True btnValidate _ BtnSubmit' = True
btnValidate _ BtnDelete' = False btnValidate _ BtnDelete' = False
nullaryPathPiece ''BtnSubmitDelete $ camelToPathPiece' 1 . dropSuffix "'" nullaryPathPiece ''ButtonSubmitDelete $ camelToPathPiece' 1 . dropSuffix "'"
-- -- Looks like a button, but is just a link (e.g. for create course, etc.) -- -- Looks like a button, but is just a link (e.g. for create course, etc.)
@ -118,8 +107,14 @@ nullaryPathPiece ''BtnSubmitDelete $ camelToPathPiece' 1 . dropSuffix "'"
-- instance PathPiece LinkButton where -- instance PathPiece LinkButton where
-- LinkButton route = ??? -- LinkButton route = ???
linkButton :: Widget -> ButtonCssClass UniWorX -> Route UniWorX -> Widget -- Alternative: Handler.Utils.simpleLink linkButton :: Widget -> [ButtonClass UniWorX] -> SomeRoute UniWorX -> Widget -- Alternative: Handler.Utils.simpleLink
linkButton lbl cls url = [whamlet| <a href=@{url} .btn .#{bcc2txt cls} role=button>^{lbl} |] linkButton lbl cls url = do
url' <- toTextUrl url
[whamlet|
$newline never
<a href=#{url'} class=#{unwords $ map toPathPiece cls} role=button>
^{lbl}
|]
-- [whamlet| -- [whamlet|
-- <form method=post action=@{url}> -- <form method=post action=@{url}>
-- <input type="hidden" name="_formid" value="identify-linkButton"> -- <input type="hidden" name="_formid" value="identify-linkButton">
@ -128,31 +123,16 @@ linkButton lbl cls url = [whamlet| <a href=@{url} .btn .#{bcc2txt cls} role=butt
-- <input .btn .#{bcc2txt cls} type="submit" value=^{lbl}> -- <input .btn .#{bcc2txt cls} type="submit" value=^{lbl}>
-- buttonForm :: Button a => Markup -> MForm (HandlerT UniWorX IO) (FormResult a, (WidgetT UniWorX IO ())) -- buttonForm :: (Button UniWorX a, Finite a) => Markup -> MForm (HandlerT UniWorX IO) (FormResult a, Widget)
buttonForm :: (Button UniWorX a, Show a) => Form a buttonForm :: (Button UniWorX a, Finite a) => Form a
buttonForm csrf = do buttonForm csrf = do
buttonIdent <- newFormIdent (res, ($ []) -> fViews) <- aFormToForm . disambiguateButtons $ combinedButtonFieldF ""
let button b = mopt (buttonField b) ("n/a"{ fsName = Just buttonIdent }) Nothing return (res, [whamlet|
(results, btnViews) <- unzip <$> mapM button [minBound..maxBound] $newline never
let widget = #{csrf}
[whamlet| $forall bView <- fViews
#{csrf} ^{fvInput bView}
$forall bView <- btnViews |])
^{fvInput bView}
|]
return (accResult results,widget)
where
accResult :: Foldable f => f (FormResult (Maybe a)) -> FormResult a
accResult = Foldable.foldr accResult' FormMissing
accResult' :: FormResult (Maybe a) -> FormResult a -> FormResult a
-- Find the single FormSuccess Just _; Expected behaviour: all buttons deliver FormFailure, except for one.
accResult' (FormSuccess (Just _)) (FormSuccess _) = FormFailure ["Ambiguous button parse"]
accResult' (FormSuccess (Just x)) _ = FormSuccess x
accResult' _ x@(FormSuccess _) = x --Safe: most buttons deliver FormFailure, one delivers FormSuccess
accResult' (FormSuccess Nothing) x = x
accResult' FormMissing _ = FormMissing
accResult' (FormFailure errs) _ = FormFailure errs

View File

@ -519,7 +519,7 @@ dbParamsFormWrap DBParamsForm{..} tableForm frag = do
return . (res,) $ do return . (res,) $ do
btnId <- newIdent btnId <- newIdent
act <- traverse toTextUrl dbParamsFormAction act <- traverse toTextUrl dbParamsFormAction
let submitField :: Field Handler SubmitButton let submitField :: Field Handler ButtonSubmit
submitField = buttonField BtnSubmit submitField = buttonField BtnSubmit
submitView :: Widget submitView :: Widget
submitView = fieldView submitField btnId "" mempty (Right BtnSubmit) False submitView = fieldView submitField btnId "" mempty (Right BtnSubmit) False

View File

@ -7,7 +7,6 @@ import Settings
import qualified Text.Blaze.Internal as Blaze (null) import qualified Text.Blaze.Internal as Blaze (null)
import qualified Data.Text as T import qualified Data.Text as T
import qualified Data.Char as Char
import Data.CaseInsensitive (CI) import Data.CaseInsensitive (CI)
import qualified Data.CaseInsensitive as CI import qualified Data.CaseInsensitive as CI
@ -200,37 +199,36 @@ identForm = identifyForm . toPathPiece
-- Buttons (new version ) -- -- Buttons (new version ) --
---------------------------- ----------------------------
data family ButtonCssClass site :: * data family ButtonClass site :: *
bcc2txt :: Show (ButtonCssClass site) => ButtonCssClass site -> Text -- a Hack; maybe define Read/Show manually class (PathPiece a, PathPiece (ButtonClass site), RenderMessage site ButtonMessage) => Button site a where
bcc2txt bcc = T.pack $ "btn-" ++ (Char.toLower <$> drop 2 (show bcc)) btnLabel :: a -> WidgetT site IO ()
class (Enum a, Bounded a, Ord a, PathPiece a) => Button site a where default btnLabel :: RenderMessage site a => a -> WidgetT site IO ()
label :: a -> WidgetT site IO () btnLabel = toWidget <=< ap getMessageRender . return
label = toWidget . toPathPiece
btnValidate :: forall p. p site -> a -> Bool btnValidate :: forall p. p site -> a -> Bool
btnValidate _ _ = True btnValidate _ _ = True
cssClass :: a -> ButtonCssClass site btnClasses :: a -> [ButtonClass site]
btnClasses _ = []
data ButtonMessage = MsgAmbiguousButtons data ButtonMessage = MsgAmbiguousButtons
| MsgWrongButtonValue | MsgWrongButtonValue
| MsgMultipleButtonValues | MsgMultipleButtonValues
deriving (Eq, Ord, Enum, Bounded, Read, Show, Generic, Typeable)
data SubmitButton = BtnSubmit data ButtonSubmit = BtnSubmit
deriving (Enum, Eq, Ord, Bounded, Read, Show) deriving (Eq, Ord, Enum, Bounded, Read, Show, Generic, Typeable)
instance Universe SubmitButton instance Universe ButtonSubmit
instance Finite SubmitButton instance Finite ButtonSubmit
nullaryPathPiece ''SubmitButton $ camelToPathPiece' 1 nullaryPathPiece ''ButtonSubmit $ camelToPathPiece' 1
buttonField :: forall a m. buttonField :: forall a m.
( Button (HandlerSite m) a ( Button (HandlerSite m) a
, Show (ButtonCssClass (HandlerSite m)) , MonadHandler m
, RenderMessage (HandlerSite m) ButtonMessage
, Monad m
) => a -> Field m a ) => a -> Field m a
-- | Already validates that the correct button press was received (result only neccessary for combinedButtonField) -- | Already validates that the correct button press was received (result only neccessary for combinedButtonField)
buttonField btn = Field{..} buttonField btn = Field{..}
@ -239,12 +237,12 @@ buttonField btn = Field{..}
fieldView :: FieldViewFunc m a fieldView :: FieldViewFunc m a
fieldView fid name attrs _val _ = let fieldView fid name attrs _val _ = let
cssClass' :: ButtonCssClass (HandlerSite m)
cssClass' = cssClass btn
validate = btnValidate (Proxy @(HandlerSite m)) btn validate = btnValidate (Proxy @(HandlerSite m)) btn
classes :: [ButtonClass (HandlerSite m)]
classes = btnClasses btn
in [whamlet| in [whamlet|
$newline never $newline never
<button .btn .#{bcc2txt cssClass'} type=submit name=#{name} value=#{toPathPiece btn} *{attrs} ##{fid} :not validate:formnovalidate>^{label btn} <button class=#{unwords $ map toPathPiece classes} type=submit name=#{name} value=#{toPathPiece btn} *{attrs} ##{fid} :not validate:formnovalidate>^{btnLabel btn}
|] |]
fieldParse [] [] = return $ Right Nothing fieldParse [] [] = return $ Right Nothing
@ -255,8 +253,6 @@ buttonField btn = Field{..}
combinedButtonField :: forall a m. combinedButtonField :: forall a m.
( Button (HandlerSite m) a ( Button (HandlerSite m) a
, Show (ButtonCssClass (HandlerSite m))
, RenderMessage (HandlerSite m) ButtonMessage
, MonadHandler m , MonadHandler m
) => [a] -> FieldSettings (HandlerSite m) -> AForm m [Maybe a] ) => [a] -> FieldSettings (HandlerSite m) -> AForm m [Maybe a]
combinedButtonField bs FieldSettings{..} = formToAForm $ do combinedButtonField bs FieldSettings{..} = formToAForm $ do
@ -280,8 +276,6 @@ combinedButtonField bs FieldSettings{..} = formToAForm $ do
combinedButtonFieldF :: forall m a. combinedButtonFieldF :: forall m a.
( Button (HandlerSite m) a ( Button (HandlerSite m) a
, Show (ButtonCssClass (HandlerSite m))
, RenderMessage (HandlerSite m) ButtonMessage
, Finite a , Finite a
, MonadHandler m , MonadHandler m
) => FieldSettings (HandlerSite m) -> AForm m [Maybe a] ) => FieldSettings (HandlerSite m) -> AForm m [Maybe a]
@ -298,26 +292,22 @@ disambiguateButtons = traverseAForm $ \case
combinedButtonField_ :: forall a m. combinedButtonField_ :: forall a m.
( Button (HandlerSite m) a ( Button (HandlerSite m) a
, Show (ButtonCssClass (HandlerSite m))
, RenderMessage (HandlerSite m) ButtonMessage
, MonadHandler m , MonadHandler m
) => [a] -> FieldSettings (HandlerSite m) -> AForm m () ) => [a] -> FieldSettings (HandlerSite m) -> AForm m ()
combinedButtonField_ = (void .) . combinedButtonField combinedButtonField_ = (void .) . combinedButtonField
combinedButtonFieldF_ :: forall m a p. combinedButtonFieldF_ :: forall m a p.
( Button (HandlerSite m) a ( Button (HandlerSite m) a
, Show (ButtonCssClass (HandlerSite m))
, RenderMessage (HandlerSite m) ButtonMessage
, MonadHandler m , MonadHandler m
, Finite a , Finite a
) => p a -> FieldSettings (HandlerSite m) -> AForm m () ) => p a -> FieldSettings (HandlerSite m) -> AForm m ()
combinedButtonFieldF_ _ = void . combinedButtonFieldF @m @a combinedButtonFieldF_ _ = void . combinedButtonFieldF @m @a
submitButton :: (Button (HandlerSite m) SubmitButton, Show (ButtonCssClass (HandlerSite m)), MonadHandler m, RenderMessage (HandlerSite m) ButtonMessage) => AForm m () submitButton :: (Button (HandlerSite m) ButtonSubmit, MonadHandler m) => AForm m ()
submitButton = combinedButtonFieldF_ (Proxy @SubmitButton) "" submitButton = combinedButtonFieldF_ (Proxy @ButtonSubmit) ""
autosubmitButton :: (Button (HandlerSite m) SubmitButton, Show (ButtonCssClass (HandlerSite m)), MonadHandler m, RenderMessage (HandlerSite m) ButtonMessage) => AForm m () autosubmitButton :: (Button (HandlerSite m) ButtonSubmit, MonadHandler m) => AForm m ()
autosubmitButton = combinedButtonFieldF_ (Proxy @SubmitButton) $ "" & addAutosubmit autosubmitButton = combinedButtonFieldF_ (Proxy @ButtonSubmit) $ "" & addAutosubmit
------------------- -------------------
-- Custom Fields -- -- Custom Fields --

View File

@ -3,6 +3,6 @@ $newline never
<form method=GET action=#{filterAction} enctype=#{filterEnctype}> <form method=GET action=#{filterAction} enctype=#{filterEnctype}>
^{filterWgdt} ^{filterWgdt}
<button> <button>
^{label BtnSubmit} ^{btnLabel BtnSubmit}
<section> <section>
^{scrolltable} ^{scrolltable}