howells699 howells699 - 1 month ago 6
Scala Question

Scala Play! Form Validation With 2 Radio Buttons

I have created a Scala Play program and would like to incorporate two radio buttons onto the same form.

  • Neither radio buttons are set a value when the page is loaded.

  • The options for both radio buttons are either yes or no.

I would like to know how to validate both radios so that Play accepts the form when:

  • Only the first no button is selected


  • When the first yes and either the second yes or no button are selected.

Any other scenario I would like an error to be shown using the bindFromRequest.fold method.

Here is my model:

package viewmodels

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


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

Here is my form:

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

Here is my controller:

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

yesNoRadioForm2.bindFromRequest.fold(formWithErrors =>
model =>
Do something

Any help would be appreciated!

Thanks in advance!

Answer Source

I use Play 2.6.3

Here goes the 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) {
    @for(error <- theForm.globalErrors) {
  @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>

here goes MyForm object defined in models package:

package models


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

  val theForm = Form(
      "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

Here is the code of my only controller:

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.
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] =>

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

Content of my routes file:

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)

And finally, we need to add this to the application.conf:

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

Hope this helps you.