2017-08-17 54 views
1

我创建了一个Scala Play程序,并希望将两个单选按钮合并到同一个表单中。斯卡拉玩!使用2个单选按钮进行表单验证

  • 当页面加载时,单选按钮都没有设置值。
  • 两个单选按钮选项为yes或no。

我想知道如何验证收音机都让游戏接受表单时:

  • 只有第一没有按钮被选中

  • 当第一个是和第二个是或否按钮被选中。

任何其他情况我想要使用bindFromRequest.fold方法显示错误。

这里是我的模型:

package viewmodels 

case class YesNoRadioViewModel2(firstRadio: String, secondRadio:String) { 

} 

/** 
    * View model for pages with yes/no style radio questions. 
    */ 
object YesNoRadioViewModel2 { 
    def apply(form: play.api.data.Form[YesNoRadioViewModel2]) = { 
    new YesNoRadioViewModel2(
     form.data.get("firstRadio").get, 
     form.data.getOrElse("secondRadio","no")) 
    } 
} 

这里是我的形式:

val yesNoRadioForm2 = Form(
mapping(
    "firstRadio" -> text.verifying(!_.isEmpty), 
    "secondRadio" -> text.verifying() 
) 
(YesNoRadioViewModel2.apply)(YesNoRadioViewModel2.unapply)) 

这里是我的控制器:

def twoRadioPost: Action[AnyContent] = MyCustomAction.async { implicit request => 

    yesNoRadioForm2.bindFromRequest.fold(formWithErrors => 
    Future(BadRequest(views.html.myproject.twoRadios(formWithErrors))) 
    , 
    model => 
    Do something 
) 
    } 

任何帮助,将不胜感激!

在此先感谢!

回答

1

我用播放2.6.3

这里去了index.scala.html

@import models.MyForm.FormData 
@(theForm:Form[FormData])(implicit messages: Messages, request:RequestHeader) 

@main("Welcome to Play") { 
    <h1>Welcome to Play!</h1> 
    @if(theForm.hasGlobalErrors) { 
    <ul> 
    @for(error <- theForm.globalErrors) { 
     <li>@error.format</li> 
    } 
    </ul> 
    } 
    @helper.form(action = helper.CSRF(routes.HomeController.processForm())){ 
    @helper.inputRadioGroup(theForm("field1"), Seq("Yes" -> "Yes", "No" -> "No")) 
    @helper.inputRadioGroup(theForm("field2"), Seq("Yes" -> "Yes", "No" -> "No")) 
    <button type="submit">Send</button> 
    } 
} 

这里进去models包中定义MyForm对象:

package models 

import play.api.data.Form 
import play.api.data.Forms._ 

/** 
    * Created by alex on 8/17/17. 
    */ 
object MyForm { 
    case class FormData(firstYesNo:Option[String], secondYesNo:Option[String]) 

    val theForm = Form(
    mapping(
     "field1" -> optional(text), 
     "field2" -> optional(text) 
    )(FormData.apply)(FormData.unapply) verifying(
     "Form failed the validation", 
     fields => fields match{ 
      case formData => formData.firstYesNo match{ 
      case None => false 
      case Some("No") => if(!formData.secondYesNo.isDefined) true else false 
      case Some("Yes") => if(formData.secondYesNo.isDefined) true else false 
      } 
     } 
    ) 
) 
} 

这是我唯一的控制器的代码:

import javax.inject._ 
import models.MyForm.theForm 
import play.api.mvc._ 

/** 
* This controller creates an `Action` to handle HTTP requests to the 
* application's home page. 
*/ 
@Singleton 
class HomeController @Inject()(cc: ControllerComponents) extends AbstractController(cc) with play.api.i18n.I18nSupport{ 

    /** 
    * Create an Action to render an HTML page. 
    * 
    * The configuration in the `routes` file means that this method 
    * will be called when the application receives a `GET` request with 
    * a path of `/`. 
    */ 
    def index() = Action { implicit request: Request[AnyContent] => 
    Ok(views.html.index(theForm)) 
    } 

    def processForm() = Action{implicit request:Request[AnyContent] => 
    theForm.bindFromRequest().fold(
     formWithErrors => BadRequest(views.html.index(formWithErrors)), 
     data => Ok("Form successfully submitted") 
    ) 
    } 
} 

内容我routes文件:

GET /       controllers.HomeController.index 

POST /processForm    controllers.HomeController.processForm 

# Map static resources from the /public folder to the /assets URL path 
GET  /assets/*file    controllers.Assets.versioned(path="/public", file: Asset) 

最后,我们需要把它添加到application.conf

play.filters.enabled += play.filters.csrf.CSRFFilter

希望这有助于你。

+0

这是辉煌的,谢谢!出于兴趣,使用两种不同的形式嵌套.bindFromRequest()。fold是不好的做法吗?谢谢 – howells699

+0

我从来没有试过这个。 POST请求将一个表单数据嵌入到其主体中,但我可以想象如果需要,可以尝试在控制器中将它绑定到两个不同的模型:) –

+0

我试过了,它工作正常。只要这不是一个普遍的坏习惯,我应该没问题。非常感谢,我很感激 – howells699

0

最后,我创建了两种不同的形式,并用它们来验证单选按钮。

我控制器

Form1.bindFromRequest.fold(
    formWithErrors => Future(BadRequest(views.html.myproject.form(formWithErrors,Form2))) 
    , 
    model => 
    if(model.radioName.equals("yes")){ 
     Form2.bindFromRequest.fold(
     formWithErrors => Future(BadRequest(views.html.myproject.form(Form1,formWithErrors))) 
     , 
     model => 
      if(model.radioName.equals("yes")){ 
      Future(Ok(GOSOMEWHERE())) 
      }else{ 
      Future(Ok(GOSOMEWHERE())) 
      }) 
    }else{ Future(Ok(GOSOMEWHERE())) }) 

我的形式

val Form1 = Form(
mapping(
    "firstRadio" -> text.verifying(!_.isEmpty) 
) 
(YesNoRadioViewModel.apply)(YesNoRadioViewModel.unapply)) 



val Form2 = Form(
mapping(
    "secondRadio" -> text.verifying() 
) 
(YesNoRadioViewModel.apply)(YesNoRadioViewModel.unapply))