2017-08-17 37 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))