我如何创建一个 Yesod 表单,我可以从下拉列表中 select 将列表作为参数传递?
How can I create a Yesod form where I can select from a dropdown list where the list is passed as an argument?
我想创建一个表单,在其中传递一个 [a]
一个参数并取回一个 MForm Handler (FormResult a, Widget)
。
我曾尝试使用 selectFieldList
等函数来实现此功能,但未能找到解决方案。我无法在 google 上的任何地方找到答案。我发现了很多示例,其中下拉列表被用作较大表单中的单个字段,但 none 其中下拉列表是整个表单本身。
编辑:
我已经成功制作了一个可以编译的表格。不幸的是,我无法判断它是否按照我想要的方式工作,因为我无法渲染它。
以下是我正在使用的关键函数(它们都可以编译):
mkCityStringM :: [PG.DbCity] -> [(T.Text, PG.DbCity)]
mkCityStringM xs = zip (map (T.pack . showDbCity) xs) xs
data ContainCity =
ContainCity
{ getCity :: PG.DbCity
}
deriving (Show)
ambiguityForm :: [PG.DbCity] -> AForm Handler ContainCity
ambiguityForm cities = ContainCity
<$> areq (selectFieldList cityMap) "City" Nothing
where
cityMap :: [(T.Text, PG.DbCity)]
cityMap = W.mkCityStringM cities
问题是当我尝试实际使用这个 table 时,我 运行 遇到了问题。这是对我来说工作得很好的代码:
locationForm :: Html -> MForm Handler (FormResult BasicLocation, Widget)
locationForm = renderDivs $ BasicLocation
<$> areq textField "City:" Nothing
<*> areq textField "Country:" (Just "United States")
postAmbiguityR :: [PG.DbCity] -> Handler Html
postAmbiguityR cs = do
(widget, enctype) <- generateFormPost locationForm
defaultLayout $ do
[whamlet|
<p>who cares
|]
另一方面,我有这段代码:
postAmbiguityR :: [PG.DbCity] -> Handler Html
postAmbiguityR cs = do
(widget, enctype) <- generateFormPost (ambiguityForm cs) --only difference
defaultLayout $ do
[whamlet|
<p> WHATEVER
|]
这给我带来了这个错误:
• Couldn't match expected type ‘blaze-markup-0.8.2.5:Text.Blaze.Internal.Markup
-> MForm (HandlerFor Base) (FormResult a0, xml0)’
with actual type ‘AForm Handler ContainCity’
• Possible cause: ‘ambiguityForm’ is applied to too many arguments
In the first argument of ‘generateFormPost’, namely
‘(ambiguityForm cs)’
In a stmt of a 'do' block:
(widget, enctype) <- generateFormPost (ambiguityForm cs)
In the expression:
do (widget, enctype) <- generateFormPost (ambiguityForm cs)
defaultLayout
$ do (do (asWidgetT . toWidget)
((blaze-markup-0.8.2.5:Text.Blaze.Internal.preEscapedText . T.pack)
"<html><header></header>
<form method="post" action="")
....)
|
132 | (widget, enctype) <- generateFormPost (ambiguityForm cs)
| ^^^^^^^^^^^^^^^^
这条错误消息对我来说没有意义。它说一个可能的原因是 ambiguity form is applied to too many arguments
但似乎并非如此,因为表格采用了 PG.DbCity 的列表,而这正是我提供的。
问题是 ambiguityForm
是 AForm
,但 generateFormPost
需要 MForm
。要将其转换为适合渲染的 MForm
,您需要使用 renderDivs
,就像您在 locationForm
示例中所做的那样。您可以 或者 在 ambiguityForm
的定义中执行此操作,这会将其 type/defintion 更改为如下所示:
ambiguityForm :: [PG.DbCity] -> Html -> MForm Handler (FormResult ContainCity, Widget)
ambiguityForm cities = renderDivs $ ContainCity ...
或可以保持ambiguityForm
不变,在使用处加上renderDivs
:
postAmbiguityR :: [PG.DbCity] -> Handler Html
postAmbiguityR cs = do
(widget, enctype) <- generateFormPost (renderDivs (ambiguityForm cs))
defaultLayout $ do
[whamlet|
<p> WHATEVER
|]
我想创建一个表单,在其中传递一个 [a]
一个参数并取回一个 MForm Handler (FormResult a, Widget)
。
我曾尝试使用 selectFieldList
等函数来实现此功能,但未能找到解决方案。我无法在 google 上的任何地方找到答案。我发现了很多示例,其中下拉列表被用作较大表单中的单个字段,但 none 其中下拉列表是整个表单本身。
编辑:
我已经成功制作了一个可以编译的表格。不幸的是,我无法判断它是否按照我想要的方式工作,因为我无法渲染它。
以下是我正在使用的关键函数(它们都可以编译):
mkCityStringM :: [PG.DbCity] -> [(T.Text, PG.DbCity)]
mkCityStringM xs = zip (map (T.pack . showDbCity) xs) xs
data ContainCity =
ContainCity
{ getCity :: PG.DbCity
}
deriving (Show)
ambiguityForm :: [PG.DbCity] -> AForm Handler ContainCity
ambiguityForm cities = ContainCity
<$> areq (selectFieldList cityMap) "City" Nothing
where
cityMap :: [(T.Text, PG.DbCity)]
cityMap = W.mkCityStringM cities
问题是当我尝试实际使用这个 table 时,我 运行 遇到了问题。这是对我来说工作得很好的代码:
locationForm :: Html -> MForm Handler (FormResult BasicLocation, Widget)
locationForm = renderDivs $ BasicLocation
<$> areq textField "City:" Nothing
<*> areq textField "Country:" (Just "United States")
postAmbiguityR :: [PG.DbCity] -> Handler Html
postAmbiguityR cs = do
(widget, enctype) <- generateFormPost locationForm
defaultLayout $ do
[whamlet|
<p>who cares
|]
另一方面,我有这段代码:
postAmbiguityR :: [PG.DbCity] -> Handler Html
postAmbiguityR cs = do
(widget, enctype) <- generateFormPost (ambiguityForm cs) --only difference
defaultLayout $ do
[whamlet|
<p> WHATEVER
|]
这给我带来了这个错误:
• Couldn't match expected type ‘blaze-markup-0.8.2.5:Text.Blaze.Internal.Markup
-> MForm (HandlerFor Base) (FormResult a0, xml0)’
with actual type ‘AForm Handler ContainCity’
• Possible cause: ‘ambiguityForm’ is applied to too many arguments
In the first argument of ‘generateFormPost’, namely
‘(ambiguityForm cs)’
In a stmt of a 'do' block:
(widget, enctype) <- generateFormPost (ambiguityForm cs)
In the expression:
do (widget, enctype) <- generateFormPost (ambiguityForm cs)
defaultLayout
$ do (do (asWidgetT . toWidget)
((blaze-markup-0.8.2.5:Text.Blaze.Internal.preEscapedText . T.pack)
"<html><header></header>
<form method="post" action="")
....)
|
132 | (widget, enctype) <- generateFormPost (ambiguityForm cs)
| ^^^^^^^^^^^^^^^^
这条错误消息对我来说没有意义。它说一个可能的原因是 ambiguity form is applied to too many arguments
但似乎并非如此,因为表格采用了 PG.DbCity 的列表,而这正是我提供的。
问题是 ambiguityForm
是 AForm
,但 generateFormPost
需要 MForm
。要将其转换为适合渲染的 MForm
,您需要使用 renderDivs
,就像您在 locationForm
示例中所做的那样。您可以 或者 在 ambiguityForm
的定义中执行此操作,这会将其 type/defintion 更改为如下所示:
ambiguityForm :: [PG.DbCity] -> Html -> MForm Handler (FormResult ContainCity, Widget)
ambiguityForm cities = renderDivs $ ContainCity ...
或可以保持ambiguityForm
不变,在使用处加上renderDivs
:
postAmbiguityR :: [PG.DbCity] -> Handler Html
postAmbiguityR cs = do
(widget, enctype) <- generateFormPost (renderDivs (ambiguityForm cs))
defaultLayout $ do
[whamlet|
<p> WHATEVER
|]