| Safe Haskell | None |
|---|---|
| Language | Haskell2010 |
Yesod.Form.Functions
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)
- runFormPRG :: (RenderMessage (HandlerSite m) FormMessage, MonadResource m, MonadHandler m) => (Markup -> MForm m (FormResult a, xml)) -> m ((FormResult a, xml), 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)]
- lookupRawFieldInput :: MonadHandler m => Text -> m [Text]
Running in MForm monad
newFormIdent :: forall (m :: Type -> Type). Monad m => MForm m Text Source #
Get a unique identifier.
Applicative/Monadic conversion
formToAForm :: forall (m :: Type -> Type) site a. (HandlerSite m ~ site, Monad m) => MForm m (FormResult a, [FieldView site]) -> AForm m a Source #
aFormToForm :: forall (m :: Type -> Type) site a. (Monad m, HandlerSite m ~ site) => AForm m a -> MForm m (FormResult a, [FieldView site] -> [FieldView site]) Source #
Arguments
| :: forall (m :: Type -> Type) a. MonadHandler m | |
| => WForm m (FormResult a) | input form |
| -> AForm m a | output form |
Fields to Forms
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
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
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)) |
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.
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) Source #
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).
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.
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) Source #
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) Source #
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) Source #
runFormGet :: MonadHandler m => (Markup -> MForm m a) -> m (a, Enctype) Source #
Post/Redirect/Get
runFormPRG :: (RenderMessage (HandlerSite m) FormMessage, MonadResource m, MonadHandler m) => (Markup -> MForm m (FormResult a, xml)) -> m ((FormResult a, xml), Enctype) Source #
Run a form for the Post/Redirect/Get pattern, so that invalid input and its validation errors survive a redirect.
Use this in both the GET and POST handlers of a route, exactly as you
would runFormPost:
- On a POST request this behaves exactly like
runFormPost(including CSRF protection). Additionally, onFormFailurethe submitted parameters are stashed in the user session so that your handler can simplyredirectback to the GET route instead of re-rendering. OnFormSuccessany previously stashed parameters for this route are cleared. OnFormMissing(anotheridentifyForm-wrapped form on the page was the one submitted) the stash is left untouched. - On a GET request, if stashed parameters exist for the current path,
they are removed from the session and the form is run against them:
the fields re-render with the user's input and validation errors, just
as a non-redirecting handler would have rendered them. A fresh CSRF
token is rendered into the form (the stashed token is discarded, and
no token check is performed on a replay). If nothing is stashed, this
behaves like
generateFormPost(the result isFormMissing).
getRegisterR :: Handler Markup
getRegisterR = do
((_res, widget), enctype) <- runFormPRG personForm
defaultLayout
[whamlet|
<form method=post action=@{RegisterR} enctype=#{enctype}>
^{widget}
|]
postRegisterR :: Handler Markup
postRegisterR = do
((res, _widget), _enctype) <- runFormPRG personForm
case res of
FormSuccess person -> do
-- insert into the database, etc.
setMessage "Registered!"
redirect RegisterR
_ -> redirect RegisterRNotes and caveats:
- The stash is keyed by request path, so the GET and POST handlers must share a route (the common Yesod pattern). Form pages on different routes do not interfere with each other; two tabs on the same path share one stash (the last failed submission wins).
- Multiple forms on one page work when wrapped with
identifyForm: on replay, only the form that was actually submitted re-renders with values and errors; the others returnFormMissingand render blank. (The stash is popped once per request and shared between calls via the per-request cache, so every form in the handler sees it.) - Uploaded files are not stashed; file fields re-render empty after the redirect.
- The stashed parameters live in the user session. With the default client-session backend the whole session must fit in a cookie (roughly 4KB), so this is unsuitable for very large forms. If the stash fails to decode, it is discarded and a blank form is generated.
- If the application has no session backend, stashing is a no-op and
this degrades to
runFormPost/generateFormPostsemantics (input will not survive the redirect). - If your POST handler re-renders on failure instead of redirecting, do not use this function: the stash would be consumed by an unrelated later GET of the same path.
- On a replay the form may even produce
FormSuccess(e.g. acheckMvalidation whose outcome depends on external state); the result is returned as-is. GET handlers normally use only the widget. - A HEAD request reads the stash without consuming it, so that
middleware such as
autoHeaddoes not eat the replay meant for the subsequent GET.
Since: 1.7.10
Generate a blank form
generateFormPost :: (RenderMessage (HandlerSite m) FormMessage, MonadHandler m) => (Markup -> MForm m (FormResult a, xml)) -> m (xml, Enctype) Source #
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) Source #
Since 1.3.11
generateFormGet :: MonadHandler m => (Markup -> MForm m a) -> m (a, Enctype) Source #
Deprecated: Will require RenderMessage in next version of Yesod
More than one form on a handler
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) ()) Source #
renderTable :: forall (m :: Type -> Type) a. Monad m => FormRender m a Source #
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 Source #
render a field inside a div
renderDivsNoLabels :: forall (m :: Type -> Type) a. Monad m => FormRender m a Source #
render a field inside a div, not displaying any label
renderBootstrap :: forall (m :: Type -> Type) a. Monad m => FormRender m a Source #
Deprecated: Please use the Yesod.Form.Bootstrap3 module.
Deprecated synonym for renderBootstrap2.
renderBootstrap2 :: forall (m :: Type -> Type) a. Monad m => FormRender m a Source #
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 Source #
checkBool :: forall (m :: Type -> Type) msg a. (Monad m, RenderMessage (HandlerSite m) msg) => (a -> Bool) -> msg -> Field m a -> Field m a Source #
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 Source #
checkMMap :: (Monad m, RenderMessage (HandlerSite m) msg) => (a -> m (Either msg b)) -> (b -> a) -> Field m a -> Field m b Source #
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 Source #
Allows you to overwrite the error message on parse error.
Utilities
fieldSettingsLabel :: RenderMessage site msg => msg -> FieldSettings site Source #
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)) Source #
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)) Source #
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 Source #
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
Arguments
| :: Text | The class to add |
| -> [(Text, Text)] | List of existing |
| -> [(Text, Text)] |
Adds a CSS class to the fsAttrs in a FieldSettings.
Examples
>>>addClass "login-form" [("class", "form-control"), ("id", "home-login")][("class","form-control login-form"),("id","home-login")]
Since: 1.6.2
Arguments
| :: Text | The class to remove |
| -> [(Text, Text)] | List of existing |
| -> [(Text, Text)] |
Removes a CSS class from the fsAttrs in a FieldSettings.
Examples
>>>removeClass "form-control" [("class","form-control login-form"),("id","home-login")][("class"," login-form"),("id","home-login")]
Since: 1.6.2
lookupRawFieldInput :: MonadHandler m => Text -> m [Text] Source #
The raw parameter values the named field was run against in this
request, whether from a direct submission or a Post/Redirect/Get
replay (runFormPRG). Empty if no form containing the field has run
with a submission in this request (e.g. generateFormPost, or an
identifyForm-wrapped form that was not the one submitted).
This lets the view of a field rendering several inputs under one name
restore all of the user's raw input after a failed submission: the
Either Text a argument a view receives can only carry the first
submitted value. Only fields run through mreq/mopt (and the
applicative/widget helpers built on them) record their values here.
Since: 1.7.11