packages feed

yesod-form 1.7.6 → 1.7.9

raw patch · 4 files changed

+162/−2 lines, 4 filesnew-uploader

Files

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