diff --git a/frontend/src/utils/async-table/async-table.ts b/frontend/src/utils/async-table/async-table.ts index 78d3fe5a0..495ac4ba3 100644 --- a/frontend/src/utils/async-table/async-table.ts +++ b/frontend/src/utils/async-table/async-table.ts @@ -322,7 +322,6 @@ abstract class TableUtil { _updateFromTableFilter(tableFilterForm) { const url = this._serializeTableFilterToURL(tableFilterForm); let callback = null; - alert(`ASYNC update from table filter: ${url}`) const focusedInput = tableFilterForm.querySelector(':focus, :active'); // focus previously focused input @@ -428,7 +427,6 @@ abstract class TableUtil { // fetches new sorted element from url with params and replaces contents of current element _updateTableFrom(url, callback?, isPopState?) { url = new URL(url); - alert(`ASYNC update table from: ${url}`) const cancelPendingUpdates = (() => { this._cancelPendingUpdates.forEach(f => f()); diff --git a/messages/uniworx/utils/buttons/de-de-formal.msg b/messages/uniworx/utils/buttons/de-de-formal.msg index 8252a3a1c..b6ec6de16 100644 --- a/messages/uniworx/utils/buttons/de-de-formal.msg +++ b/messages/uniworx/utils/buttons/de-de-formal.msg @@ -1,8 +1,9 @@ -# SPDX-FileCopyrightText: 2022 Gregor Kleen ,Steffen Jost ,Winnie Ros ,Sarah Vaupel +# SPDX-FileCopyrightText: 2022-2024 Gregor Kleen ,Steffen Jost ,Winnie Ros ,Sarah Vaupel ,David Mosbach # # SPDX-License-Identifier: AGPL-3.0-or-later BtnSubmit: Senden +BtnApplyFilter: Filter Anwenden BtnAbort: Abbrechen BtnDelete: Löschen BtnRegister: Anmelden diff --git a/messages/uniworx/utils/buttons/en-eu.msg b/messages/uniworx/utils/buttons/en-eu.msg index a83a7b3aa..37228f057 100644 --- a/messages/uniworx/utils/buttons/en-eu.msg +++ b/messages/uniworx/utils/buttons/en-eu.msg @@ -1,8 +1,9 @@ -# SPDX-FileCopyrightText: 2022 Steffen Jost ,Winnie Ros ,Sarah Vaupel +# SPDX-FileCopyrightText: 2022-2024 Steffen Jost ,Winnie Ros ,Sarah Vaupel ,David Mosbach # # SPDX-License-Identifier: AGPL-3.0-or-later BtnSubmit: Submit +BtnApplyFilter: Apply Filter BtnAbort: Abort BtnDelete: Delete BtnRegister: Register diff --git a/src/Auth/Dummy.hs b/src/Auth/Dummy.hs index 06bf4985e..c7ae31e57 100644 --- a/src/Auth/Dummy.hs +++ b/src/Auth/Dummy.hs @@ -1,4 +1,4 @@ --- SPDX-FileCopyrightText: 2022 Felix Hamann ,Gregor Kleen ,Sarah Vaupel +-- SPDX-FileCopyrightText: 2022-2024 Felix Hamann ,Gregor Kleen ,Sarah Vaupel ,David Mosbach -- -- SPDX-License-Identifier: AGPL-3.0-or-later @@ -80,6 +80,7 @@ dummyLogin = AuthPlugin{..} , formEncoding = loginEnctype , formAttrs = [("uw-no-navigate-away-prompt","")] , formSubmit = FormSubmit + , formCustomBtn = Nothing :: Maybe ButtonSubmit , formAnchor = Just "login--dummy" :: Maybe Text } $(widgetFile "widgets/dummy-login-form/dummy-login-form") diff --git a/src/Auth/LDAP.hs b/src/Auth/LDAP.hs index 329bb0a29..026f5534f 100644 --- a/src/Auth/LDAP.hs +++ b/src/Auth/LDAP.hs @@ -1,4 +1,4 @@ --- SPDX-FileCopyrightText: 2022 Felix Hamann ,Gregor Kleen ,Sarah Vaupel ,Steffen Jost ,Steffen Jost +-- SPDX-FileCopyrightText: 2022-2024 Felix Hamann ,Gregor Kleen ,Sarah Vaupel ,Steffen Jost ,Steffen Jost ,David Mosbach -- -- SPDX-License-Identifier: AGPL-3.0-or-later @@ -273,6 +273,7 @@ campusLogin pool mode = AuthPlugin{..} , formEncoding = loginEnctype , formAttrs = [("uw-no-navigate-away-prompt","")] , formSubmit = FormSubmit + , formCustomBtn = Nothing :: Maybe ButtonSubmit , formAnchor = Just "login--campus" :: Maybe Text } $(widgetFile "widgets/campus-login/campus-login-form") diff --git a/src/Auth/PWHash.hs b/src/Auth/PWHash.hs index e857d8dcc..84088168d 100644 --- a/src/Auth/PWHash.hs +++ b/src/Auth/PWHash.hs @@ -1,4 +1,4 @@ --- SPDX-FileCopyrightText: 2022 Felix Hamann ,Gregor Kleen ,Sarah Vaupel +-- SPDX-FileCopyrightText: 2022-2024 Felix Hamann ,Gregor Kleen ,Sarah Vaupel ,David Mosbach -- -- SPDX-License-Identifier: AGPL-3.0-or-later @@ -92,6 +92,7 @@ hashLogin pwHashAlgo = AuthPlugin{..} , formEncoding = loginEnctype , formAttrs = [("uw-no-navigate-away-prompt","")] , formSubmit = FormSubmit + , formCustomBtn = Nothing :: Maybe ButtonSubmit , formAnchor = Just "login--hash" :: Maybe Text } $(widgetFile "widgets/hash-login-form/hash-login-form") diff --git a/src/Foundation/I18n.hs b/src/Foundation/I18n.hs index 8fc50b5e4..dbfd87256 100644 --- a/src/Foundation/I18n.hs +++ b/src/Foundation/I18n.hs @@ -1,4 +1,4 @@ --- SPDX-FileCopyrightText: 2022-23 Gregor Kleen ,Sarah Vaupel ,Sarah Vaupel ,Steffen Jost ,Steffen Jost ,Winnie Ros +-- SPDX-FileCopyrightText: 2022-24 Gregor Kleen ,Sarah Vaupel ,Sarah Vaupel ,Steffen Jost ,Steffen Jost ,Winnie Ros ,David Mosbach -- -- SPDX-License-Identifier: AGPL-3.0-or-later @@ -584,6 +584,7 @@ instance RenderMessage UniWorX ShortWeekDay where renderMessage _ ls (ShortWeekDay wDay) = pack . snd $ wDays (getTimeLocale' ls) !! (fromEnum wDay `mod` 7) embedRenderMessage ''UniWorX ''ButtonSubmit id +embedRenderMessage ''UniWorX ''ButtonApplyFilter id instance RenderMessage UniWorX VolatileClusterSettingsKey where renderMessage foundation ls = \case diff --git a/src/Foundation/Instances/ButtonClass.hs b/src/Foundation/Instances/ButtonClass.hs index fd4ffb974..d64a58ee6 100644 --- a/src/Foundation/Instances/ButtonClass.hs +++ b/src/Foundation/Instances/ButtonClass.hs @@ -1,4 +1,4 @@ --- SPDX-FileCopyrightText: 2022 Wolfgang Witt +-- SPDX-FileCopyrightText: 2022-2024 Wolfgang Witt ,David Mosbach -- -- SPDX-License-Identifier: AGPL-3.0-or-later @@ -35,3 +35,6 @@ instance PathPiece (ButtonClass UniWorX) where instance Button UniWorX ButtonSubmit where btnClasses BtnSubmit = [BCIsButton, BCPrimary] + +instance Button UniWorX ButtonApplyFilter where + btnClasses BtnApplyFilter = [BCIsButton, BCPrimary] diff --git a/src/Handler/Admin/Test.hs b/src/Handler/Admin/Test.hs index dc235ac3f..f8f99e770 100644 --- a/src/Handler/Admin/Test.hs +++ b/src/Handler/Admin/Test.hs @@ -1,4 +1,4 @@ --- SPDX-FileCopyrightText: 2022 Gregor Kleen ,Steffen Jost +-- SPDX-FileCopyrightText: 2022-2024 Gregor Kleen ,Steffen Jost ,David Mosbach -- -- SPDX-License-Identifier: AGPL-3.0-or-later @@ -249,6 +249,7 @@ postAdminTestR = do , formEncoding = formEnctype , formAttrs = [] , formSubmit = FormSubmit + , formCustomBtn = Nothing :: Maybe ButtonSubmit , formAnchor = Just FIDAdminDemo } showDemoResult @@ -260,6 +261,7 @@ postAdminTestR = do , formEncoding = miEnc , formAttrs = [] , formSubmit = FormSubmit + , formCustomBtn = Nothing :: Maybe ButtonSubmit , formAnchor = Just miIdent } [whamlet| @@ -283,6 +285,7 @@ postAdminTestR = do , formEncoding = i18nEnc , formAttrs = [] , formSubmit = FormSubmit + , formCustomBtn = Nothing :: Maybe ButtonSubmit , formAnchor = Just i18nIdent } [whamlet| diff --git a/src/Handler/Course/ParticipantInvite.hs b/src/Handler/Course/ParticipantInvite.hs index 53eff795d..8eb29f112 100644 --- a/src/Handler/Course/ParticipantInvite.hs +++ b/src/Handler/Course/ParticipantInvite.hs @@ -1,4 +1,4 @@ --- SPDX-FileCopyrightText: 2022-23 Sarah Vaupel , Steffen Jost +-- SPDX-FileCopyrightText: 2022-24 Sarah Vaupel , Steffen Jost ,David Mosbach -- -- SPDX-License-Identifier: AGPL-3.0-or-later @@ -292,6 +292,7 @@ handleAddUserR tid ssh csh tdesc ttyp = do , formEncoding = confirmEnctype , formAttrs = [] , formSubmit = FormNoSubmit + , formCustomBtn = Nothing :: Maybe ButtonSubmit , formAnchor = Nothing :: Maybe Text } $(widgetFile "course/add-user/confirmation-wrapper") diff --git a/src/Handler/Course/User.hs b/src/Handler/Course/User.hs index 81af8b6e4..fce40d718 100644 --- a/src/Handler/Course/User.hs +++ b/src/Handler/Course/User.hs @@ -1,4 +1,4 @@ --- SPDX-FileCopyrightText: 2022 Gregor Kleen ,Winnie Ros +-- SPDX-FileCopyrightText: 2022-2024 Gregor Kleen ,Winnie Ros ,David Mosbach -- -- SPDX-License-Identifier: AGPL-3.0-or-later @@ -118,6 +118,7 @@ courseUserProfileSection course@(Entity cid Course{..}) (Entity uid User{ userSh , formEncoding = regButtonEnctype , formAttrs = [] , formSubmit = FormSubmit + , formCustomBtn = Nothing :: Maybe ButtonSubmit , formAnchor = Just registrationButtonFrag } formResult regButtonRes $ \case @@ -193,6 +194,7 @@ courseUserNoteSection (Entity cid Course{..}) (Entity uid _) = do , formEncoding = noteEnctype , formAttrs = [] , formSubmit = FormSubmit + , formCustomBtn = Nothing :: Maybe ButtonSubmit , formAnchor = Just noteFrag } formResult noteRes $ \mbNote -> do diff --git a/src/Handler/Firm.hs b/src/Handler/Firm.hs index 32655b867..e04ccdb78 100644 --- a/src/Handler/Firm.hs +++ b/src/Handler/Firm.hs @@ -1,4 +1,4 @@ --- SPDX-FileCopyrightText: 2023 Steffen Jost +-- SPDX-FileCopyrightText: 2023-2024 Steffen Jost ,David Mosbach -- -- SPDX-License-Identifier: AGPL-3.0-or-later @@ -211,6 +211,7 @@ runFirmActionFormPost cid route isAdmin acts = do , formEncoding = faEnctype , formAttrs = [] , formSubmit = FormSubmit + , formCustomBtn = Nothing :: Maybe ButtonSubmit , formAnchor = Just faAnchor } firmActionHandler route isAdmin faRes diff --git a/src/Handler/Profile.hs b/src/Handler/Profile.hs index 8429c04c7..68264c79f 100644 --- a/src/Handler/Profile.hs +++ b/src/Handler/Profile.hs @@ -1,4 +1,4 @@ --- SPDX-FileCopyrightText: 2022 Gregor Kleen ,Sarah Vaupel ,Sarah Vaupel ,Steffen Jost ,Winnie Ros +-- SPDX-FileCopyrightText: 2022-2024 Gregor Kleen ,Sarah Vaupel ,Sarah Vaupel ,Steffen Jost ,Winnie Ros ,David Mosbach -- -- SPDX-License-Identifier: AGPL-3.0-or-later @@ -551,6 +551,7 @@ serveProfileR (uid, user@User{..}) = do , formEncoding = formEnctype , formAttrs = [] , formSubmit = FormSubmit + , formCustomBtn = Nothing :: Maybe ButtonSubmit , formAnchor = Just ProfileSettings } tokenForm = @@ -560,6 +561,7 @@ serveProfileR (uid, user@User{..}) = do , formEncoding = tokenEnctype , formAttrs = [] , formSubmit = FormNoSubmit + , formCustomBtn = Nothing :: Maybe ButtonSubmit , formAnchor = Just ProfileResetTokens } tokenExplanation = $(i18nWidgetFile "profile/tokenExplanation") diff --git a/src/Handler/School.hs b/src/Handler/School.hs index 48693c517..c8a45c026 100644 --- a/src/Handler/School.hs +++ b/src/Handler/School.hs @@ -1,4 +1,4 @@ --- SPDX-FileCopyrightText: 2022 Gregor Kleen ,Sarah Vaupel ,Steffen Jost ,Winnie Ros +-- SPDX-FileCopyrightText: 2022-2024 Gregor Kleen ,Sarah Vaupel ,Steffen Jost ,Winnie Ros ,David Mosbach -- -- SPDX-License-Identifier: AGPL-3.0-or-later @@ -171,6 +171,7 @@ postSchoolEditR ssh = do , formEncoding = sfEnctype , formAttrs = [] , formSubmit = FormSubmit + , formCustomBtn = Nothing :: Maybe ButtonSubmit , formAnchor = Nothing :: Maybe Text } @@ -232,6 +233,7 @@ postSchoolNewR = do , formEncoding = sfEnctype , formAttrs = [] , formSubmit = FormSubmit + , formCustomBtn = Nothing :: Maybe ButtonSubmit , formAnchor = Nothing :: Maybe Text } diff --git a/src/Handler/Sheet/PersonalisedFiles.hs b/src/Handler/Sheet/PersonalisedFiles.hs index 2d521aca4..ed580d256 100644 --- a/src/Handler/Sheet/PersonalisedFiles.hs +++ b/src/Handler/Sheet/PersonalisedFiles.hs @@ -1,4 +1,4 @@ --- SPDX-FileCopyrightText: 2022 Gregor Kleen ,Sarah Vaupel ,Winnie Ros +-- SPDX-FileCopyrightText: 2022-2024 Gregor Kleen ,Sarah Vaupel ,Winnie Ros ,David Mosbach -- -- SPDX-License-Identifier: AGPL-3.0-or-later @@ -425,7 +425,7 @@ getPersonalFilesR cId mbsid = do { formMethod = GET , formAction = SomeRoute <$> cRoute , formEncoding = psfEnctype - , formAttrs = formAttrs def <> bool mempty [("uw-no-navigate-away-prompt", ""), ("target", "_blank")] isModal + , formAttrs = formAttrs (def @(FormSettings UniWorX)) <> bool mempty [("uw-no-navigate-away-prompt", ""), ("target", "_blank")] isModal } getSPersonalFilesR :: TermId -> SchoolId -> CourseShorthand -> SheetName -> Handler TypedContent diff --git a/src/Handler/SystemMessage.hs b/src/Handler/SystemMessage.hs index 05b327e00..0cc34a96e 100644 --- a/src/Handler/SystemMessage.hs +++ b/src/Handler/SystemMessage.hs @@ -1,4 +1,4 @@ --- SPDX-FileCopyrightText: 2022 Gregor Kleen ,Sarah Vaupel ,Sarah Vaupel ,Steffen Jost +-- SPDX-FileCopyrightText: 2022-2024 Gregor Kleen ,Sarah Vaupel ,Sarah Vaupel ,Steffen Jost ,David Mosbach -- -- SPDX-License-Identifier: AGPL-3.0-or-later @@ -135,6 +135,7 @@ postMessageR cID = do , formEncoding = modifyEnctype , formAttrs = [] , formSubmit = FormSubmit + , formCustomBtn = Nothing :: Maybe ButtonSubmit , formAnchor = Nothing :: Maybe Text } translationAddModal = modal [whamlet|_{MsgSystemMessageAddTranslation}|] . Right $ @@ -144,6 +145,7 @@ postMessageR cID = do , formEncoding = addTransEnctype , formAttrs = [] , formSubmit = FormSubmit + , formCustomBtn = Nothing :: Maybe ButtonSubmit , formAnchor = Nothing :: Maybe Text } translationsEditModal @@ -154,6 +156,7 @@ postMessageR cID = do , formEncoding = transEnctype , formAttrs = [] , formSubmit = FormNoSubmit + , formCustomBtn = Nothing :: Maybe ButtonSubmit , formAnchor = Nothing :: Maybe Text } [whamlet| diff --git a/src/Handler/Utils/Table/Pagination.hs b/src/Handler/Utils/Table/Pagination.hs index 9bf324887..a7cecb711 100644 --- a/src/Handler/Utils/Table/Pagination.hs +++ b/src/Handler/Utils/Table/Pagination.hs @@ -643,12 +643,13 @@ defaultDBSFilterLayout filterWdgt filterEnctype filterAction scrolltable = $(widgetFile "table/layout-filter-default") where filterForm = wrapForm filterWdgt FormSettings - { formMethod = GET - , formAction = Just filterAction - , formEncoding = filterEnctype - , formAttrs = [("class", "table-filter-form"), ("autocomplete", "off")] - , formSubmit = FormSubmit --FormAutoSubmit --TODO not for sync-tables --FormCustomSubmit MsgFilterSubmit - , formAnchor = Nothing :: Maybe Text + { formMethod = GET + , formAction = Just filterAction + , formEncoding = filterEnctype + , formAttrs = [("class", "table-filter-form"), ("autocomplete", "off")] + , formSubmit = FormSubmit --FormSubmit --FormAutoSubmit --TODO not for sync-tables + , formCustomBtn = Just BtnApplyFilter + , formAnchor = Nothing :: Maybe Text } @@ -1017,6 +1018,7 @@ dbParamsFormWrap DBTable{ dbtIdent } DBParamsForm{..} tableForm frag = do , formEncoding = enctype , formAttrs = dbParamsFormAttrs , formSubmit = dbParamsFormSubmit + , formCustomBtn = Nothing :: Maybe ButtonSubmit , formAnchor = Just $ WithIdent dbtIdent ("form" :: Text) } @@ -1184,6 +1186,7 @@ dbTable PSValidator{..} dbtable@DBTable{ dbtIdent = dbtIdent'@(toPathPiece -> db , formEncoding = csvExportEnctype , formAttrs = [] , formSubmit = FormSubmit + , formCustomBtn = Nothing :: Maybe ButtonSubmit , formAnchor = Just $ wIdent "csv-export" } csvImportWdgt' = wrapForm csvImportWdgt FormSettings @@ -1192,6 +1195,7 @@ dbTable PSValidator{..} dbtable@DBTable{ dbtIdent = dbtIdent'@(toPathPiece -> db , formEncoding = csvImportEnctype , formAttrs = [] , formSubmit = FormNoSubmit + , formCustomBtn = Nothing :: Maybe ButtonSubmit , formAnchor = Just $ wIdent "csv-import" } csvImportExplanation :: Widget @@ -1382,6 +1386,7 @@ dbTable PSValidator{..} dbtable@DBTable{ dbtIdent = dbtIdent'@(toPathPiece -> db , formEncoding = csvImportConfirmEnctype , formAttrs = [] , formSubmit = FormNoSubmit + , formCustomBtn = Nothing :: Maybe ButtonSubmit , formAnchor = Nothing :: Maybe Text } @@ -1594,6 +1599,7 @@ dbTable PSValidator{..} dbtable@DBTable{ dbtIdent = dbtIdent'@(toPathPiece -> db , formEncoding = pagesizeEnc , formAttrs = [("class", "pagesize"), ("autocomplete", "off")] , formSubmit = FormAutoSubmit + , formCustomBtn = Nothing :: Maybe ButtonSubmit , formAnchor = Just $ wIdent "pagesize-form" } showPagesizeWdgt = toEnum (fromIntegral rowCount) > minimum (pagesizeOptions referencePagesize) diff --git a/src/Utils/Form.hs b/src/Utils/Form.hs index 18c96c289..19e8f2135 100644 --- a/src/Utils/Form.hs +++ b/src/Utils/Form.hs @@ -1,4 +1,4 @@ --- SPDX-FileCopyrightText: 2023 Felix Hamann ,Gregor Kleen ,Sarah Vaupel ,Sarah Vaupel ,Steffen Jost ,Steffen Jost ,Wolfgang Witt +-- SPDX-FileCopyrightText: 2023-2024 Felix Hamann ,Gregor Kleen ,Sarah Vaupel ,Sarah Vaupel ,Steffen Jost ,Steffen Jost ,Wolfgang Witt ,David Mosbach -- -- SPDX-License-Identifier: AGPL-3.0-or-later @@ -398,6 +398,16 @@ instance Finite ButtonSubmit nullaryPathPiece ''ButtonSubmit $ camelToPathPiece' 1 +-- | Filter button +data ButtonApplyFilter = BtnApplyFilter + deriving (Eq, Ord, Enum, Bounded, Read, Show, Generic) + +instance Universe ButtonApplyFilter +instance Finite ButtonApplyFilter + +nullaryPathPiece ''ButtonApplyFilter $ camelToPathPiece' 2 + + buttonField :: forall a m. ( Button (HandlerSite m) a , MonadHandler m @@ -1123,23 +1133,25 @@ data FormSubmitType = FormNoSubmit | FormSubmit | FormDualSubmit | FormAutoSubmi instance Universe FormSubmitType instance Finite FormSubmitType -data FormSettings site = forall p. PathPiece p => FormSettings +data FormSettings site = forall p b. (PathPiece p, Button site b) => FormSettings { formMethod :: StdMethod , formAction :: Maybe (SomeRoute site) , formEncoding :: Enctype , formAttrs :: [(Text, Text)] , formSubmit :: FormSubmitType + , formCustomBtn :: Maybe b , formAnchor :: Maybe p } -instance Default (FormSettings site) where +instance (Button site ButtonSubmit) => Default (FormSettings site) where def = FormSettings - { formMethod = POST - , formAction = Nothing - , formEncoding = UrlEncoded - , formAttrs = [] - , formSubmit = FormSubmit - , formAnchor = Nothing :: Maybe Text + { formMethod = POST + , formAction = Nothing + , formEncoding = UrlEncoded + , formAttrs = [] + , formSubmit = FormSubmit + , formCustomBtn = Nothing :: Maybe ButtonSubmit + , formAnchor = Nothing :: Maybe Text } wrapForm :: Button site ButtonSubmit => WidgetT site IO () -> FormSettings site -> WidgetT site IO () @@ -1152,6 +1164,19 @@ wrapForm' btn formWidget FormSettings{..} = do let hasAction = isJust formActionUrl $(widgetFile "widgets/form/form") +buttonViewFallback :: forall site a b. (Button site a, Button site b) + => Maybe b + -> a + -> WidgetT site IO () +buttonViewFallback Nothing btn = buttonView btn +buttonViewFallback (Just btn) _ = buttonView btn + +btnLabelFallback :: forall site a b. (Button site a, Button site b) + => Maybe b + -> a + -> WidgetT site IO () +btnLabelFallback Nothing btn = btnLabel btn +btnLabelFallback (Just btn) _ = btnLabel btn ------------------- -- Form Renderer -- diff --git a/templates/widgets/form/form.hamlet b/templates/widgets/form/form.hamlet index 371a7c701..b89901472 100644 --- a/templates/widgets/form/form.hamlet +++ b/templates/widgets/form/form.hamlet @@ -1,6 +1,6 @@ $newline never -$# SPDX-FileCopyrightText: 2022 Sarah Vaupel ,Steffen Jost +$# SPDX-FileCopyrightText: 2022-2024 Sarah Vaupel ,Steffen Jost ,David Mosbach $# $# SPDX-License-Identifier: AGPL-3.0-or-later @@ -12,12 +12,13 @@ $# Wrapper for all kinds of forms ^{formWidget} $of FormSubmit ^{formWidget} - ^{buttonView btn} + ^{buttonViewFallback formCustomBtn btn} $of FormDualSubmit - ^{buttonView btn} + ^{buttonViewFallback formCustomBtn btn} ^{formWidget} - ^{buttonView btn} + ^{buttonViewFallback formCustomBtn btn} $of FormAutoSubmit ^{formWidget}