colinrmitchell.com

Blog

Yesod custom control for UTCTime

Posted Wednesday, April 23rd 2014 in Programming - Permalink

If you are using a Yesod site with MongoDB for Persistent, you will probably come to realize that Day and TimeOfDay are not available as Haskell datatypes to be used in your models. As far as I am aware, UTCTime is the only date/time data type available. Unfortunately, Yesod.Form.Fields does not contain a ready-to-use field function for UTCTime in applicative forms. Here is a custom field that you can use to display and edit UTCTime fields. This field sets the type of the <input> to date-time, which allows browsers to use their own custom date-time forms.

utcTimeField :: Monad m => RenderMessage (HandlerSite m) FormMessage => Field m UTCTime
utcTimeField = Field
     { fieldParse = parseHelper parseTime'
     , fieldView = \theId name attrs val isReq -> toWidget [hamlet|
$newline never
<input id="#{theId}" name="#{name}" type="datetime" *{attrs} :isReq:required="" value="#{showVal val}">
|]
     , fieldEnctype = UrlEncoded
     }
    where
       showVal = either id (pack . formatTime defaultTimeLocale "%F %T")

parseTime' :: Text -> Either FormMessage UTCTime
parseTime' theText = 
    maybe 
       (Left MsgInvalidTimeFormat) 
       (\x -> Right x) 
       (Data.Time.Format.parseTime defaultTimeLocale "%F %T" $ unpack theText)

This field requires the following imports:

import Data.Time.Clock
import Data.Time
import System.Locale (defaultTimeLocale)
import qualified Data.Time.Format (parseTime)

You can use it as follows:

someForm = renderDivs $ MyDataType
    <$> areq utcTimeField "Date" Nothing


List Posts Newest Posts Page 1Next Page