Yesod で1ページに複数個フォームがある場合は identifyForm を使う
resolver lts-5.4 で確認。
問題
1ページに複数個フォームがある場合、runFormPost
はそれぞれのフォームの区別をしてくれません。どういうことかというと、例えば下記のような2つのフォームを利用するとします。
data AFormData = AFormData Text aForm :: Html -> MForm Handler (FormResult AFormData, Widget) aForm = renderDivs $ AFormData <$> areq textField "A Text" Nothing data BFormData = BFormData Text bForm :: Html -> MForm Handler (FormResult BFormData, Widget) bForm = renderDivs $ BFormData <$> areq textField "B Text" Nothing
この2つのフォームを1つのページに配置し、ブラウザーでアクセスしどちらか一方のフォームに “Hello” とでも入力し送信します。すると runFormPost aForm
も runFormPost bForm
も返り値の FormResult Xxx
型の部分が FormSuccess xxx
となり、xxx
の部分はそれぞれ AFormData "Hello"
・BFormData "Hello"
となります。
これは困ります。
解決
identifyForm
を使います。
identifyForm :: Monad m => Text -- ^ Form identification string. -> (Html -> MForm m (FormResult a, WidgetT (HandlerSite m) IO ())) -> (Html -> MForm m (FormResult a, WidgetT (HandlerSite m) IO ()))
第1引数にユニークな文字列を指定してください。
aForm = identifyForm "a-form" $ renderDivs $ AFormData <$> areq textField "A Text" Nothing
これで、対応するフォームに入力されたときだけ runFormPost
が FormSuccess
を返すようになります。
参考
Issue yesod-web/yesod #649