yesod-form 1.7.6 → 1.7.9
raw patch · 4 files changed
+162/−2 lines, 4 filesnew-uploader
Files
- ChangeLog.md +16/−0
- Yesod/Form/Fields.hs +48/−1
- Yesod/Form/Option.hs +96/−0
- yesod-form.cabal +2/−1
ChangeLog.md view
@@ -1,5 +1,21 @@ # ChangeLog for yesod-form +## 1.7.9++* Added `checkboxesField'` for creating checkbox in more correct way than original `checkboxesField`+ Function `checkboxesField` marked as deprecated. [#1843](https://github.com/yesodweb/yesod/pull/1843)++## 1.7.8++* Added `radioField'` for creating radio button in more correct way than original `radioField`.+ Function `radioField` marked as deprecated. [#1842](https://github.com/yesodweb/yesod/pull/1842)++## 1.7.7++* Added `optionsFromList'` to create an OptionList from a List, using the PathPiece instance for the external value and+a custom function for the user-facing value. Also added `optionsEnum'` to create an OptionList from an enumeration+[#1828](https://github.com/yesodweb/yesod/pull/1828)+ ## 1.7.6 * Added `datetimeLocalField` for creating a html `<input type="datetime-local">` [#1817](https://github.com/yesodweb/yesod/pull/1817)
Yesod/Form/Fields.hs view
@@ -48,9 +48,11 @@ , selectFieldList , selectFieldListGrouped , radioField+ , radioField' , radioFieldList , withRadioField , checkboxesField+ , checkboxesField' , checkboxesFieldList , multiSelectField , multiSelectFieldList@@ -123,6 +125,9 @@ import Data.Char (isHexDigit) +{-# DEPRECATED radioField "This function seems to have a bug (label could not be found with byLabel algorithm)" #-}+{-# DEPRECATED checkboxesField "This function seems to have a bug (label could not be found with byLabel algorithm)" #-}+ defaultFormMessage :: FormMessage -> Text defaultFormMessage = englishFormMessage @@ -529,6 +534,27 @@ #{optionDisplay opt} |] }++-- | Creates an input with @type="checkbox"@ for selecting multiple options.+checkboxesField' :: Eq a+ => HandlerFor site (OptionList a)+ -> Field (HandlerFor site) [a]+checkboxesField' ioptlist = (multiSelectField ioptlist)+ { fieldView =+ \theId name attrs val _isReq -> do+ opts <- olOptions <$> handlerToWidget ioptlist+ let optselected (Left _) _ = False+ optselected (Right vals) opt = optionInternalValue opt `elem` vals+ [whamlet|+ <span ##{theId}>+ $forall opt <- opts+ <input id=#{theId}-#{optionExternalValue opt} type=checkbox name=#{name} value=#{optionExternalValue opt} *{attrs} :optselected val opt:checked>+ <label for=#{theId}-#{optionExternalValue opt}>+ #{optionDisplay opt}+ |]+ }++ -- | Creates an input with @type="radio"@ for selecting one option. radioField :: (Eq a, RenderMessage site FormMessage) => HandlerFor site (OptionList a)@@ -552,6 +578,28 @@ |]) +-- | Creates an input with @type="radio"@ for selecting one option.+--+-- @since 1.7.8+radioField' :: (Eq a, RenderMessage site FormMessage)+ => HandlerFor site (OptionList a)+ -> Field (HandlerFor site) a+radioField' = withRadioField+ (\theId optionWidget -> [whamlet|+$newline never+<.radio>+ ^{optionWidget}+ <label for=#{theId}-none>+ _{MsgSelectNone}+|])+ (\theId value _isSel text optionWidget -> [whamlet|+$newline never+<.radio>+ ^{optionWidget}+ <label for=#{theId}-#{value}>+ \#{text}+|])+ -- | Allows the user to place the option radio widget somewhere in -- the template. -- For example: If you want a table of radio options to select.@@ -578,7 +626,6 @@ optFun theId value isSel display [whamlet| <input id=#{theId}-#{(value)} type=radio name=#{name} value=#{(value)} :isSel:checked *{attrs}> |]- -- | Creates a group of radio buttons to answer the question given in the message. Radio buttons are used to allow differentiating between an empty response (@Nothing@) and a no response (@Just False@). Consider using the simpler 'checkBoxField' if you don't need to make this distinction. --
+ Yesod/Form/Option.hs view
@@ -0,0 +1,96 @@+{-# LANGUAGE FlexibleContexts #-}++module Yesod.Form.Option where++import Yesod.Core+import Yesod.Form.Fields++-- | Creates an `OptionList` from a `List`, using the `PathPiece` instance for+-- the external value and a custom function for the user-facing value.+--+-- @since 1.7.7+--+-- PathPiece instances should provide suitable external values, since path+-- pieces serve to be exposed through URLs or HTML anyway. Show/Read instances+-- are avoided here since they could leak internal representations to forms,+-- query params, javascript etc.+--+-- === __Example usage__+--+-- > data UserRole = URSalesTeam | URSalesHead | URTechTeam | URTechHead+-- >+-- > instance PathPiece UserDepartment where+-- > toPathPiece = \case+-- > URSalesTeam -> "sales-team"+-- > URSalesHead -> "sales-head"+-- > URTechTeam -> "tech-team"+-- > URTechHead -> "tech-head"+-- > fromPathPiece = \case+-- > "sales-team" -> Just URSalesTeam+-- > "sales-head" -> Just URSalesHead+-- > "tech-team" -> Just URTechTeam+-- > "tech-head" -> Just URTechHead+-- > _ -> Nothing+-- >+-- > userRoleOptions ::+-- > (MonadHandler m, RenderMessage (HandlerSite m) msg) => m (OptionList UserRole)+-- > userRoleOptions = optionsFromList' userRoles toMsg+-- > where+-- > userRoles = [URSalesTeam, URSalesHead, URTechTeam, URTechHead]+-- > toMsg :: UserRole -> Text+-- > toMsg = \case+-- > URSalesTeam -> "Sales Team"+-- > URSalesHead -> "Head of Sales Team"+-- > URTechTeam -> "Tech Team"+-- > URTechHead -> "Head of Tech Team"+--+-- userRoleOptions, will produce an OptionList with the following attributes:+--+-- > +----------------+----------------+--------------------++-- > | Internal Value | External Value | User-facing Value |+-- > +----------------+----------------+--------------------++-- > | URSalesTeam | sales-team | Sales Team |+-- > +----------------+----------------+--------------------++-- > | URSalesHead | sales-head | Head of Sales Team |+-- > +----------------+----------------+--------------------++-- > | URTechTeam | tech-team | Tech Team |+-- > +----------------+----------------+--------------------++-- > | URTechHead | tech-head | Head of Tech Team |+-- > +----------------+----------------+--------------------++--+-- Note that the type constraint allows localizable messages in place of toMsg (see+-- https://en.wikipedia.org/wiki/Yesod_(web_framework)#Localizable_messages).++optionsFromList' ::+ MonadHandler m+ => RenderMessage (HandlerSite m) msg+ => PathPiece a+ => [a]+ -> (a -> msg)+ -> m (OptionList a)+optionsFromList' lst toDisplay = do+ mr <- getMessageRender+ pure $ mkOptionList $ flip map lst $ \v -> Option+ { optionDisplay = mr $ toDisplay v+ , optionInternalValue = v+ , optionExternalValue = toPathPiece v+ }++-- | Creates an `OptionList` from an `Enum`.+--+-- @since 1.7.7+--+-- optionsEnum' == optionsFromList' [minBound..maxBound]+--+-- Creates an `OptionList` containing every constructor of `a`, so that these+-- constructors do not need to be typed out. Bounded and Enum instances must+-- exist for `a` to use this.+optionsEnum' ::+ MonadHandler m+ => RenderMessage (HandlerSite m) msg+ => PathPiece a+ => Enum a+ => Bounded a+ => (a -> msg)+ -> m (OptionList a)+optionsEnum' = optionsFromList' [minBound..maxBound]
yesod-form.cabal view
@@ -1,6 +1,6 @@ cabal-version: >= 1.10 name: yesod-form-version: 1.7.6+version: 1.7.9 license: MIT license-file: LICENSE author: Michael Snoyman <michael@snoyman.com>@@ -46,6 +46,7 @@ build-depends: network-uri >= 2.6 exposed-modules: Yesod.Form+ Yesod.Form.Option Yesod.Form.Types Yesod.Form.Functions Yesod.Form.Bootstrap3