yesod-form-1.7.9: Form handling support for Yesod Web Framework

Safe Haskell | None
Language | Haskell2010

Yesod.Form.Functions

Contents

- Running in MForm monad
- Applicative/Monadic conversion
- Fields to Forms
- Run a form
- Generate a blank form
- More than one form on a handler
- Rendering
- Validation
- Utilities

Synopsis

- newFormIdent :: forall (m :: Type -> Type). Monad m => MForm m Text
- askParams :: forall (m :: Type -> Type). Monad m => MForm m (Maybe Env)
- askFiles :: forall (m :: Type -> Type). Monad m => MForm m (Maybe FileEnv)
- formToAForm :: forall (m :: Type -> Type) site a. (HandlerSite m ~ site, Monad m) => MForm m (FormResult a, [FieldView site]) -> AForm m a
- aFormToForm :: forall (m :: Type -> Type) site a. (Monad m, HandlerSite m ~ site) => AForm m a -> MForm m (FormResult a, [FieldView site] -> [FieldView site])
- mFormToWForm :: forall (m :: Type -> Type) site a. (MonadHandler m, HandlerSite m ~ site) => MForm m (a, FieldView site) -> WForm m a
- wFormToAForm :: forall (m :: Type -> Type) a. MonadHandler m => WForm m (FormResult a) -> AForm m a
- wFormToMForm :: forall (m :: Type -> Type) site a. (MonadHandler m, HandlerSite m ~ site) => WForm m a -> MForm m (a, [FieldView site])
- wreq :: forall site (m :: Type -> Type) a. (RenderMessage site FormMessage, HandlerSite m ~ site, MonadHandler m) => Field m a -> FieldSettings site -> Maybe a -> WForm m (FormResult a)
- wreqMsg :: forall site msg (m :: Type -> Type) a. (RenderMessage site msg, HandlerSite m ~ site, MonadHandler m) => Field m a -> FieldSettings site -> msg -> Maybe a -> WForm m (FormResult a)
- wopt :: forall (m :: Type -> Type) site a. (MonadHandler m, HandlerSite m ~ site) => Field m a -> FieldSettings site -> Maybe (Maybe a) -> WForm m (FormResult (Maybe a))
- mreq :: forall site (m :: Type -> Type) a. (RenderMessage site FormMessage, HandlerSite m ~ site, MonadHandler m) => Field m a -> FieldSettings site -> Maybe a -> MForm m (FormResult a, FieldView site)
- mreqMsg :: forall site msg (m :: Type -> Type) a. (RenderMessage site msg, HandlerSite m ~ site, MonadHandler m) => Field m a -> FieldSettings site -> msg -> Maybe a -> MForm m (FormResult a, FieldView site)
- mopt :: forall site (m :: Type -> Type) a. (site ~ HandlerSite m, MonadHandler m) => Field m a -> FieldSettings site -> Maybe (Maybe a) -> MForm m (FormResult (Maybe a), FieldView site)
- areq :: forall site (m :: Type -> Type) a. (RenderMessage site FormMessage, HandlerSite m ~ site, MonadHandler m) => Field m a -> FieldSettings site -> Maybe a -> AForm m a
- areqMsg :: forall site msg (m :: Type -> Type) a. (RenderMessage site msg, HandlerSite m ~ site, MonadHandler m) => Field m a -> FieldSettings site -> msg -> Maybe a -> AForm m a
- aopt :: forall (m :: Type -> Type) a. MonadHandler m => Field m a -> FieldSettings (HandlerSite m) -> Maybe (Maybe a) -> AForm m (Maybe a)
- runFormPost :: (RenderMessage (HandlerSite m) FormMessage, MonadResource m, MonadHandler m) => (Markup -> MForm m (FormResult a, xml)) -> m ((FormResult a, xml), Enctype)
- runFormPostNoToken :: MonadHandler m => (Markup -> MForm m a) -> m (a, Enctype)
- runFormGet :: MonadHandler m => (Markup -> MForm m a) -> m (a, Enctype)
- generateFormPost :: (RenderMessage (HandlerSite m) FormMessage, MonadHandler m) => (Markup -> MForm m (FormResult a, xml)) -> m (xml, Enctype)
- generateFormGet' :: MonadHandler m => (Markup -> MForm m (FormResult a, xml)) -> m (xml, Enctype)
- generateFormGet :: MonadHandler m => (Markup -> MForm m a) -> m (a, Enctype)
- identifyForm :: forall (m :: Type -> Type) a. Monad m => Text -> (Markup -> MForm m (FormResult a, WidgetFor (HandlerSite m) ())) -> Markup -> MForm m (FormResult a, WidgetFor (HandlerSite m) ())
- type FormRender (m :: Type -> Type) a = AForm m a -> Markup -> MForm m (FormResult a, WidgetFor (HandlerSite m) ())
- renderTable :: forall (m :: Type -> Type) a. Monad m => FormRender m a
- renderDivs :: forall (m :: Type -> Type) a. Monad m => FormRender m a
- renderDivsNoLabels :: forall (m :: Type -> Type) a. Monad m => FormRender m a
- renderBootstrap :: forall (m :: Type -> Type) a. Monad m => FormRender m a
- renderBootstrap2 :: forall (m :: Type -> Type) a. Monad m => FormRender m a
- check :: forall (m :: Type -> Type) msg a. (Monad m, RenderMessage (HandlerSite m) msg) => (a -> Either msg a) -> Field m a -> Field m a
- checkBool :: forall (m :: Type -> Type) msg a. (Monad m, RenderMessage (HandlerSite m) msg) => (a -> Bool) -> msg -> Field m a -> Field m a
- checkM :: (Monad m, RenderMessage (HandlerSite m) msg) => (a -> m (Either msg a)) -> Field m a -> Field m a
- checkMMap :: (Monad m, RenderMessage (HandlerSite m) msg) => (a -> m (Either msg b)) -> (b -> a) -> Field m a -> Field m b
- customErrorMessage :: forall (m :: Type -> Type) a. Monad m => SomeMessage (HandlerSite m) -> Field m a -> Field m a
- fieldSettingsLabel :: RenderMessage site msg => msg -> FieldSettings site
- parseHelper :: (Monad m, RenderMessage site FormMessage) => (Text -> Either FormMessage a) -> [Text] -> [FileInfo] -> m (Either (SomeMessage site) (Maybe a))
- parseHelperGen :: (Monad m, RenderMessage site msg) => (Text -> Either msg a) -> [Text] -> [FileInfo] -> m (Either (SomeMessage site) (Maybe a))
- convertField :: forall (m :: Type -> Type) a b. Functor m => (a -> b) -> (b -> a) -> Field m a -> Field m b
- addClass :: Text -> [(Text, Text)] -> [(Text, Text)]
- removeClass :: Text -> [(Text, Text)] -> [(Text, Text)]

# Running in MForm monad

newFormIdent :: forall (m :: Type -> Type). Monad m => MForm m Text #

Get a unique identifier.

askParams :: forall (m :: Type -> Type). Monad m => MForm m (Maybe Env) #

askFiles :: forall (m :: Type -> Type). Monad m => MForm m (Maybe FileEnv) #

# Applicative/Monadic conversion

formToAForm :: forall (m :: Type -> Type) site a. (HandlerSite m ~ site, Monad m) => MForm m (FormResult a, [FieldView site]) -> AForm m a #

aFormToForm :: forall (m :: Type -> Type) site a. (Monad m, HandlerSite m ~ site) => AForm m a -> MForm m (FormResult a, [FieldView site] -> [FieldView site]) #

mFormToWForm #

Arguments

:: forall (m :: Type -> Type) site a. (MonadHandler m, HandlerSite m ~ site) |
=> MForm m (a, FieldView site) | input form
-> WForm m a | output form

Converts a monadic form `MForm` into another monadic form `WForm`.

Since: 1.4.14

wFormToAForm #

Arguments

:: forall (m :: Type -> Type) a. MonadHandler m |
=> WForm m (FormResult a) | input form
-> AForm m a | output form

Converts a monadic form `WForm` into an applicative form `AForm`.

Since: 1.4.14

wFormToMForm #

Arguments

:: forall (m :: Type -> Type) site a. (MonadHandler m, HandlerSite m ~ site) |
=> WForm m a | input form
-> MForm m (a, [FieldView site]) | output form

Converts a monadic form `WForm` into another monadic form `MForm`.

Since: 1.4.14

# Fields to Forms

wreq #

Arguments

:: forall site (m :: Type -> Type) a. (RenderMessage site FormMessage, HandlerSite m ~ site, MonadHandler m) |
=> Field m a | form field
-> FieldSettings site | settings for this field
-> Maybe a | optional default value
-> WForm m (FormResult a) |

Converts a form field into monadic form `WForm`. This field requires a value and will return `FormFailure` if left empty.

Since: 1.4.14

wreqMsg #

Arguments

:: forall site msg (m :: Type -> Type) a. (RenderMessage site msg, HandlerSite m ~ site, MonadHandler m) |
=> Field m a | form field
-> FieldSettings site | settings for this field
-> msg | message to use in case value is Nothing
-> Maybe a | optional default value
-> WForm m (FormResult a) |

Same as `wreq` but with your own message to be rendered in case the value is not provided.

This is useful when you have several required fields on the page and you want to differentiate between which fields were left blank. Otherwise the user sees "Value is required" multiple times, which is ambiguous.

Since: 1.6.7

wopt #

Arguments

:: forall (m :: Type -> Type) site a. (MonadHandler m, HandlerSite m ~ site) |
=> Field m a | form field
-> FieldSettings site | settings for this field
-> Maybe (Maybe a) | optional default value
-> WForm m (FormResult (Maybe a)) |

Converts a form field into monadic form `WForm`. This field is optional, i.e. if filled in, it returns 'Just a', if left empty, it returns `Nothing`. Arguments are the same as for `wreq` (apart from type of default value).

Since: 1.4.14

mreq #

Arguments

:: forall site (m :: Type -> Type) a. (RenderMessage site FormMessage, HandlerSite m ~ site, MonadHandler m) |
=> Field m a | form field
-> FieldSettings site | settings for this field
-> Maybe a | optional default value
-> MForm m (FormResult a, FieldView site) |

Converts a form field into monadic form. This field requires a value and will return `FormFailure` if left empty.

mreqMsg #

Arguments

:: forall site msg (m :: Type -> Type) a. (RenderMessage site msg, HandlerSite m ~ site, MonadHandler m) |
=> Field m a | form field
-> FieldSettings site | settings for this field
-> msg | Message to use in case value is Nothing
-> Maybe a | optional default value
-> MForm m (FormResult a, FieldView site) |

Same as `mreq` but with your own message to be rendered in case the value is not provided.

This is useful when you have several required fields on the page and you want to differentiate between which fields were left blank. Otherwise the user sees "Value is required" multiple times, which is ambiguous.

Since: 1.6.6

mopt :: forall site (m :: Type -> Type) a. (site ~ HandlerSite m, MonadHandler m) => Field m a -> FieldSettings site -> Maybe (Maybe a) -> MForm m (FormResult (Maybe a), FieldView site) #

Converts a form field into monadic form. This field is optional, i.e. if filled in, it returns 'Just a', if left empty, it returns `Nothing`. Arguments are the same as for `mreq` (apart from type of default value).

areq #

Arguments

:: forall site (m :: Type -> Type) a. (RenderMessage site FormMessage, HandlerSite m ~ site, MonadHandler m) |
=> Field m a | form field
-> FieldSettings site | settings for this field
-> Maybe a | optional default value
-> AForm m a |

Applicative equivalent of `mreq`.

areqMsg #

Arguments

:: forall site msg (m :: Type -> Type) a. (RenderMessage site msg, HandlerSite m ~ site, MonadHandler m) |
=> Field m a | form field
-> FieldSettings site | settings for this field
-> msg | message to use in case value is Nothing
-> Maybe a | optional default value
-> AForm m a |

Same as `areq` but with your own message to be rendered in case the value is not provided.

This is useful when you have several required fields on the page and you want to differentiate between which fields were left blank. Otherwise the user sees "Value is required" multiple times, which is ambiguous.

Since: 1.6.7

aopt :: forall (m :: Type -> Type) a. MonadHandler m => Field m a -> FieldSettings (HandlerSite m) -> Maybe (Maybe a) -> AForm m (Maybe a) #

Applicative equivalent of `mopt`.

# Run a form

runFormPost :: (RenderMessage (HandlerSite m) FormMessage, MonadResource m, MonadHandler m) => (Markup -> MForm m (FormResult a, xml)) -> m ((FormResult a, xml), Enctype) #

This function is used to both initially render a form and to later extract results from it. Note that, due to CSRF protection and a few other issues, forms submitted via GET and POST are slightly different. As such, be sure to call the relevant function based on how the form will be submitted, not the current request method.

For example, a common case is displaying a form on a GET request and having the form submit to a POST page. In such a case, both the GET and POST handlers should use `runFormPost`.

runFormPostNoToken :: MonadHandler m => (Markup -> MForm m a) -> m (a, Enctype) #

runFormGet :: MonadHandler m => (Markup -> MForm m a) -> m (a, Enctype) #

# Generate a blank form

generateFormPost :: (RenderMessage (HandlerSite m) FormMessage, MonadHandler m) => (Markup -> MForm m (FormResult a, xml)) -> m (xml, Enctype) #

Similar to `runFormPost`, except it always ignores the currently available environment. This is necessary in cases like a wizard UI, where a single page will both receive and incoming form and produce a new, blank form. For general usage, you can stick with `runFormPost`.

generateFormGet' :: MonadHandler m => (Markup -> MForm m (FormResult a, xml)) -> m (xml, Enctype) #

Since 1.3.11

generateFormGet :: MonadHandler m => (Markup -> MForm m a) -> m (a, Enctype) #

Deprecated: Will require RenderMessage in next version of Yesod

# More than one form on a handler

identifyForm #

Arguments

:: forall (m :: Type -> Type) a. Monad m |
=> Text | Form identification string.
-> (Markup -> MForm m (FormResult a, WidgetFor (HandlerSite m) ())) |
-> Markup |
-> MForm m (FormResult a, WidgetFor (HandlerSite m) ()) |

Creates a hidden field on the form that identifies it. This identification is then used to distinguish between missing and wrong form data when a single handler contains more than one form.

For instance, if you have the following code on your handler:

    ((fooRes, fooWidget), fooEnctype) <- runFormPost fooForm
    ((barRes, barWidget), barEnctype) <- runFormPost barForm

Then replace it with

    ((fooRes, fooWidget), fooEnctype) <- runFormPost $ identifyForm "foo" fooForm
    ((barRes, barWidget), barEnctype) <- runFormPost $ identifyForm "bar" barForm

Note that it's your responsibility to ensure that the identification strings are unique (using the same one twice on a single handler will not generate any errors). This allows you to create a variable number of forms and still have them work even if their number or order change between the HTML generation and the form submission.

# Rendering

type FormRender (m :: Type -> Type) a = AForm m a -> Markup -> MForm m (FormResult a, WidgetFor (HandlerSite m) ()) #

renderTable :: forall (m :: Type -> Type) a. Monad m => FormRender m a #

Render a form into a series of tr tags. Note that, in order to allow you to add extra rows to the table, this function does not wrap up the resulting HTML in a table tag; you must do that yourself.

renderDivs :: forall (m :: Type -> Type) a. Monad m => FormRender m a #

render a field inside a div

renderDivsNoLabels :: forall (m :: Type -> Type) a. Monad m => FormRender m a #

render a field inside a div, not displaying any label

renderBootstrap :: forall (m :: Type -> Type) a. Monad m => FormRender m a #

Deprecated: Please use the Yesod.Form.Bootstrap3 module.

Deprecated synonym for `renderBootstrap2`.

renderBootstrap2 :: forall (m :: Type -> Type) a. Monad m => FormRender m a #

Render a form using Bootstrap v2-friendly shamlet syntax. If you're using Bootstrap v3, then you should use the functions from module Yesod.Form.Bootstrap3.

Sample Hamlet:

     <form .form-horizontal method=post action=@{ActionR} enctype=#{formEnctype}>
       <fieldset>
         <legend>_{MsgLegend}
         $case result
           $of FormFailure reasons
             $forall reason <- reasons
               <div .alert .alert-error>#{reason}
           $of _
         ^{formWidget}
         <div .form-actions>
           <input .btn .primary type=submit value=_{MsgSubmit}>

Since 1.3.14

# Validation

check :: forall (m :: Type -> Type) msg a. (Monad m, RenderMessage (HandlerSite m) msg) => (a -> Either msg a) -> Field m a -> Field m a #

checkBool :: forall (m :: Type -> Type) msg a. (Monad m, RenderMessage (HandlerSite m) msg) => (a -> Bool) -> msg -> Field m a -> Field m a #

Return the given error message if the predicate is false.

checkM :: (Monad m, RenderMessage (HandlerSite m) msg) => (a -> m (Either msg a)) -> Field m a -> Field m a #

checkMMap :: (Monad m, RenderMessage (HandlerSite m) msg) => (a -> m (Either msg b)) -> (b -> a) -> Field m a -> Field m b #

Same as `checkM`, but modifies the datatype.

In order to make this work, you must provide a function to convert back from the new datatype to the old one (the second argument to this function).

Since 1.1.2

customErrorMessage :: forall (m :: Type -> Type) a. Monad m => SomeMessage (HandlerSite m) -> Field m a -> Field m a #

Allows you to overwrite the error message on parse error.

# Utilities

fieldSettingsLabel :: RenderMessage site msg => msg -> FieldSettings site #

Generate a `FieldSettings` from the given label.

parseHelper :: (Monad m, RenderMessage site FormMessage) => (Text -> Either FormMessage a) -> [Text] -> [FileInfo] -> m (Either (SomeMessage site) (Maybe a)) #

A helper function for creating custom fields.

This is intended to help with the common case where a single input value is required, such as when parsing a text field.

Since 1.1

parseHelperGen :: (Monad m, RenderMessage site msg) => (Text -> Either msg a) -> [Text] -> [FileInfo] -> m (Either (SomeMessage site) (Maybe a)) #

A generalized version of `parseHelper`, allowing any type for the message indicating a bad parse.

Since 1.3.6

convertField :: forall (m :: Type -> Type) a b. Functor m => (a -> b) -> (b -> a) -> Field m a -> Field m b #

Since a `Field` cannot be a `Functor`, it is not obvious how to "reuse" a Field on a `newtype` or otherwise equivalent type. This function allows you to convert a `Field m a` to a `Field m b` assuming you provide a bidirectional conversion between the two, through the first two functions.

A simple example:

    import Data.Monoid
    sumField :: (Functor m, Monad m, RenderMessage (HandlerSite m) FormMessage) => Field m (Sum Int)
    sumField = convertField Sum getSum intField

Another example, not using a newtype, but instead creating a Lazy Text field:

    import qualified Data.Text.Lazy as TL
    TextField :: (Functor m, Monad m, RenderMessage (HandlerSite m) FormMessage) => Field m TL.Text
    lazyTextField = convertField TL.fromStrict TL.toStrict textField

Since 1.3.16

addClass #

Arguments

:: Text | The class to add
-> [(Text, Text)] | List of existing `fsAttrs`
-> [(Text, Text)] |

Adds a CSS class to the `fsAttrs` in a `FieldSettings`.

#### Examples

Expand

    >>> addClass "login-form" [("class", "form-control"), ("id", "home-login")]
    [("class","form-control login-form"),("id","home-login")]

Since: 1.6.2

removeClass #

Arguments

:: Text | The class to remove
-> [(Text, Text)] | List of existing `fsAttrs`
-> [(Text, Text)] |

Removes a CSS class from the `fsAttrs` in a `FieldSettings`.

#### Examples

Expand

    >>> removeClass "form-control" [("class","form-control login-form"),("id","home-login")]
    [("class","  login-form"),("id","home-login")]

Since: 1.6.2