This is my code based on the examples:
val signupForm = Form(
tuple(
"firstname" -> nonEmptyText,
"lastname" -> nonEmptyText,
"email" -> nonEmptyText,
"password1" -> nonEmptyText,
"password2" -> nonEmptyText,
"phone" -> optional(text)
) verifying ("That email address already exists please contact an administrator.", result => result match {
case (firstname, lastname, email, password1, password2, phone) => !User.checkexists(email).isDefined
})
)
but there is no example showing how i might add another check in there - say comparing the password1 & password2... or a third check...
where can i add another 'verifying ' bit?
thanks
val signupForm = Form(
tuple(
...
) verifying (...)
verifying (...)
verifying (...)
)
In your case:
val signupForm = Form(
tuple(
"firstname" -> nonEmptyText,
"lastname" -> nonEmptyText,
"email" -> nonEmptyText,
"password1" -> nonEmptyText,
"password2" -> nonEmptyText,
"phone" -> optional(text)
) verifying ("That email address already exists please contact an administrator.", result => result match {
case (firstname, lastname, email, password1, password2, phone) => !User.checkexists(email).isDefined
})
verifying (...)
)
Related
I am using Scala Forms. I have set a keys and values in Form Data that is enclosed into a tuple having String as data type.
val userForm = Form(
tuple(
"k1" -> optional(v1),
"k2" -> optional(v2),
"k3" -> optional(v3)
)
)
and access this Form values using
val (k1, k2, k3) = userForm.bindFromRequest.get
It is working fine.
What I need is that. I want to make k2 and k3 keys as Option[String] type and k1 as normal String type. So, when I place Option[String] to k2, k3 keys.
val userForm = Form(
tuple(
"k1" -> optional(v1),
"k2" -> Some(optional(v2)),
"k3" -> Some(optional(v3))
)
)
It throws error -
type mismatch;
found : (String, Some[play.api.data.Mapping[Option[String]]])
required: (String, play.api.data.Mapping[?])
Any suggestions ?
Scala-Form provides you a way of making it so that you can have Option values via using its optional field type.
So... when you declare a form as,
val userForm = Form(
tuple(
"k1" -> optional(text),
"k2" -> optional(text),
"k3" -> optional(text)
)
)
Then, the userForm already declares the values k1, k2 and k3 to be Option[String].
So to have it your needed way, declare the form with k1 as normal text and others as option(text)
val userForm = Form(
tuple(
"k1" -> text,
"k2" -> optional(text),
"k3" -> optional(text)
)
)
A form mapping can also define optional values using Forms.optional:
case class UserOptionalData(name: String, email: Option[String])
val userFormOptional = Form(
mapping(
"name" -> text,
"email" -> optional(email)
)(UserOptionalData.apply)(UserOptionalData.unapply)
) //example taken from play docs
This maps to an Option[A] in output, which is None if no form value is found.
Change k1 from optional to text to make it a compulsory field. Make k1 text
val userForm = Form(
tuple(
"k1" -> text,
"k2" -> Some(optional(text)),
"k3" -> Some(optional(text))
)
)
I have tried to validate form input only for numbers, I it pop-up an error message
Read from stdout:
D:\PROJECTS\test\SimpleRequest19-DBCon_Session\app\controllers\Prodcuts.scala:24:
not found: value number
Here is the helper
#helper.inputText(productCreateForm("prosupprice"),'_help -> "",'_label -> "Supplier Price",'_showConstraints -> false)</div>
here is the validation function
private val productCreateForm: Form[Product] = Form(
mapping(
"proname" -> nonEmptyText,
"proprice" -> nonEmptyText,
"prodes" -> nonEmptyText,
"probrand" -> nonEmptyText,
"protype" -> nonEmptyText,
"prosupplier" -> nonEmptyText,
"prosupcode" -> nonEmptyText,
"prosupprice"-> number
)(Product.apply)(Product.unapply)
)
Check your imports. You should have play.api.data.Forms._ maybe you have only play.api.data.Forms.nonEmptyText
Help with Scala forms validation,
Here is the case class for the form data:
case class Data(
firstName: String,
lastName: String,
email: String,
confirm_email: String,
password: String,
confirm_password: String)
}
And the Scala Form:
val form = Form(
mapping(
"firstName" -> nonEmptyText,
"lastName" -> nonEmptyText,
"email" -> email,
"confirm_email" -> email,
"password" -> nonEmptyText(minLength = 8),
"confirm_password" -> nonEmptyText(minLength = 8))(Data.apply)(Data.unapply))
Now the problem is we need to validate the "email" and "confirm" email, but the problem is we need to create tuples or mapping. And so what is the best way to handle these kinds of form validation situations. It can be easily done by only using tuples and not mapping it to any case class.
But what can be done if we are requried to use mapping and case classes in forms.
First things first, I'd get rid of the confirm_email and confirm_password fields since they're redundant in the Data model. After this operation, it'll look like this:
case class Data(
firstName: String,
lastName: String,
email: String,
password: String)
Next, your form mapping needs to be updated:
val form = Form[Data](
mapping(
"firstName" -> nonEmptyText,
"lastName" -> nonEmptyText,
"email" -> tuple(
"email1" -> email,
"email2" -> email
).verifying(Messages("form.error.emailNotEquals"), email => email._1 == email._2),
"password" -> tuple(
"pass1" -> nonEmptyText(minLength = 8),
"pass2" -> nonEmptyText(minLength = 8)
).verifying(Messages("form.error.passwordNotEquals"), password => password._1 == password._2)
)((firstName, lastName, email, password) => Data(firstName, lastName, email._1, password._1))
((form: Data) => Some((form.firstName, form.lastName, (form.email, form.email), ("", ""))))
)
Two changes are required:
Nested mapping with validation both for email and password fields.
Custom apply and unapply method implementation in order to map the form with six fields into the models case class with four fields.
Notice that the custom unapply method doesn't set values for password fields since it's a desired behaviour in virtually all cases.
Finally, your view must be altered to refer new form tuple mapping correctly. For instance, fields for email should look as follows:
#helper.inputText(dataForm("email.email1"))
#helper.inputText(dataForm("email.email2"))
Fields which don't use new tuple mappings stay unchanged.
Based on #JacobusR's answer how can I program a form in the controller that allows me to send it to the view as a Form type with all one-side table columns mapping and many-side table seq-mapping?
Something like this:
In the Controller
private val DirectorateAndItsServiceAreas: Form[???] = Form(
mapping(
"dirCode" -> nonEmptyText,
"name" -> text,
"serviceAreaRow" -> seq( /* don't have and don't want serviceAreasRow in Directorate table */
mapping(
"areaCode" -> nonEmptyText,
"dirCode" -> nonEmptyText,
"name" -> text
)(ServiceArea.apply)(ServiceArea.unapply)
)
)(Directorate.apply)(Directorate.unapply)
)
In the View
#(DirectorateAndItsServiceAreasForm: Form[Directorate/ServiceArea],...
I'm creating a scala application using Play framework and mongoDB. I manage to have the connections up using Leon Play-Salat. I have a model
case class Person(
id: ObjectId = new ObjectId,
fname: String,
mname: String,
lname: String
)
In my controller I need to map it to a form
val personForm: Form[Person] = Form(
// Defines a mapping that will handle Contact values
mapping(
"id" -> of[ObjectId],
"fname" -> nonEmptyText,
"mname" -> text,
"lname" -> nonEmptyText
)(Person.apply)(Person.unapply))
How do I map the ObjectID to the form ? I'm getting error Object not found for the ObjectId.
Manage to get it working
val personForm: Form[Person] = Form(
// Defines a mapping that will handle Contact values
mapping(
"id" -> ignored(new ObjectId),
"fname" -> nonEmptyText,
"mname" -> text,
"lname" -> nonEmptyText
)(Person.apply)(Person.unapply))
I'm trying to do a CRUD function thus need the ID.
Found using own constructor and deconstructor is better
val personForm: Form[Person] = Form(
mapping(
"fname" -> nonEmptyText,
"mname" -> text,
"lname" -> nonEmptyText
)((fname, mname, lname) => Person(new ObjectId, fname, mname, lname))
((person: Person) => Some((person.fname, person.mname, person.lname))) )