diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -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)
diff --git a/Yesod/Form/Fields.hs b/Yesod/Form/Fields.hs
--- a/Yesod/Form/Fields.hs
+++ b/Yesod/Form/Fields.hs
@@ -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.
 --
diff --git a/Yesod/Form/Option.hs b/Yesod/Form/Option.hs
new file mode 100644
--- /dev/null
+++ b/Yesod/Form/Option.hs
@@ -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]
diff --git a/yesod-form.cabal b/yesod-form.cabal
--- a/yesod-form.cabal
+++ b/yesod-form.cabal
@@ -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
