Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you create a Playframework 2.0 Form with a field that is conditionally required?

Let's say I want to have a Form with a field, email, that is only required if they didn't put in their phone number in. Also the phone number is only required if they didn't put in their email, how would I do this?

I would like to do something like this, if requiredNoValid existed.

import play.api.data._
import play.api.data.Forms._
import play.api.data.validation.Constraints._

case class User(email: Option[String] = None, age: Option[Int])

val userForm = Form(
  mapping(
    "email" -> email.verifying(requiredNoValid(phoneNumber)),
    "phoneNumber" -> number.verifying(requiredNoValid(email))
  )(User.apply)(User.unapply)
)

I have built my own solution for this in Play 1.X, but I would like to abandon most of that and use the Play 2 forms to do this for me if the functionality is there or if there is a way to do this by implementing a Validator or Constraint.

like image 813
myyk Avatar asked Sep 20 '12 01:09

myyk


2 Answers

You can also add verifying on several fields. For a simple example:

val userForm = Form(
  mapping(
    "email" -> optional(email),
    "phoneNumber" -> optional(number)
  ) verifying("You must provide your email or phone number.", { 
      case (e, p) => 
        isValidEmail(e) || isValidPhoneNumber(p)
  })(User.apply)(User.unapply)
)

Inside of the outer verifying now, you have access to both the email and phone number and can do cross validation.

like image 177
Andrew Conner Avatar answered Sep 17 '22 17:09

Andrew Conner


This solution is for Java, but I'm sure you could so something similar if you're using scala You could get the bound form data once you submit and validate it. If its not valid, you can reject the form with some error message. For example:

//Get filled form
Form<User> filledForm = userForm.bindFromRequest();
//Get the user object
User u = filledForm.get();

//If both are not empty
if(u.phoneNumber.isEmpty() && u.email.isEmpty()){
    filledForm.reject("email", "You must provide a valid email or phone number");
} 
like image 24
Omar Wagih Avatar answered Sep 19 '22 17:09

Omar Wagih