AFormとMForm
YesodにはAFormとMFormがある、「あぷりかてぃぶふぉーむ」と「モナドふぉーむ」らしいが、名前をみても何が違うのが分からないのがYesod...簡単にいうと、AFormは「お手軽版」でMFormが「好きにやれよ版」。
だと思ってる...
Formの情報をhaskellの型へ流し込んだり、その逆をやったりするもの、Formをいじくる関数を定義しておいて、generateFormPost関数とかでフォームを作成する、なんでGetとかPostでフォームの作成関数が違うのかは、CSRFとかのタグの出力があるとかないとかでちがいがある。
サンプルはこちらに置いときます。
AForm
ほとんどの場合が、これで済みそうな感じ、普通のフォームを上から並べてくならAFormで十分。
ただ、renderDivs関数とかでくるむ必要があるので、ちょっと細工をしたい場合に、邪魔になるケースがある、多分こでが気に入らなかったらMForm使えってことかな。
その他に、 renderDivsNoLabels関数とかrenderTable関数とかある、サンプルはrenderBootstrap3をBootStrap用の3種類のフォームで出力してみた。
-- Formの情報がここにはいる data FileForm = FileForm { fileInfo :: FileInfo , inpText :: Text } fileUploadAFormInline :: Form FileForm fileUploadAFormInline = renderBootstrap3 BootstrapInlineForm $ getAform fileUploadAFormBasic :: Form FileForm fileUploadAFormBasic = renderBootstrap3 BootstrapBasicForm $ getAform fileUploadAFormHorizon :: Form FileForm fileUploadAFormHorizon = renderBootstrap3 (BootstrapHorizontalForm (ColXs 2) (ColXs 8) (ColXs 2) (ColXs 6)) $ getAform getAform :: AForm Handler FileForm getAform = FileForm <$> fileAFormReq fs <*> areq textField tfs Nothing where fs = FieldSettings { fsLabel = "ファイル" , fsTooltip = Nothing , fsId = Nothing , fsName = Just "media" , fsAttrs = [ ("class", "form-group") , ("placeholder", "File description") ] } tfs = FieldSettings { fsLabel = "なんかいれろ" , fsTooltip = Nothing , fsId = Just "inptext" , fsName = Just "inptext" , fsAttrs = [ ("class", "form-group form-control") , ("placeholder", "input text") ] }
フォームの情報を取得する変数を<$>と<*>でいれていく、Formコントロールにスタイル等を設定したい場合は、FieldSettingsで属性情報を追加する。
でこれをHandlerで走らせて、Widgetを取得する
getFormexamR :: Handler Html getFormexamR = do (formAWidgetBasic, formAEnctypeBasic) <- generateFormPost fileUploadAFormBasic (formAWidgetInline, formAEnctypeInline) <- generateFormPost fileUploadAFormInline (formAWidgetHorizon, formAEnctypeHorizon) <- generateFormPost fileUploadAFormHorizon ((res, widget), enctype) <- runFormPost fileUploadMForm defaultLayout $ do setTitle "Form Example!!!" $(widgetFile "formexam")
MForm
こっちは細かくフォームを作成できる方、mreqでつなげるぐらいで、基本的にAFormと一緒、mreqでFormから値を取り出すときに、ResultとViewが別々にとれるので、手動でFileFormへつめてやるところぐらいが違う、HTMLを細かく調整できる。
fileUploadMForm :: Html -> MForm Handler (FormResult FileForm, Widget) fileUploadMForm extra = do let fsMedia = FieldSettings { fsLabel = "" , fsTooltip = Nothing , fsId = Nothing , fsName = Just "media" , fsAttrs = [ ("class", "uploadFile") , ("style", "display:none") , ("placeholder", "") ] } let fsText = FieldSettings { fsLabel = "なんか" , fsTooltip = Nothing , fsId = Nothing , fsName = Just "inptext" , fsAttrs = [ ("class", "form-group form-control") , ("placeholder", "") ] } (fileInfoRes, fileInfoView) <- mreq fileField fsMedia Nothing (inpTextRes, inpTextView) <- mreq textField fsText Nothing let fileRes = FileForm <$> fileInfoRes <*> inpTextRes let widget = do [whamlet| #{extra} <label> <div class="form-group"> <span class="btn btn-default">Upload ^{fvInput fileInfoView} ^{fvInput inpTextView} |] return (fileRes, widget)
これをHandlerでつかう、resにはFileFormでwidgetにはwhamletで作成したwidgetがはいる。
... ((res, widget), enctype) <- runFormPost fileUploadMForm ...
出力はこんな感じ
HTMLの出力は4種類出力してみましたが、BootstrapとHTMLの知識は皆無ですので、あまり突っ込まないでください。
0 件のコメント:
コメントを投稿