How can I combine 2 validators together in play2? - forms

For example, I want a input should be nonEmptyText and email.
If the user doesn't input anything, it will show error message The field is required, if user inputs an invalid email, it will show Invalid email.
But I found, I can just use one:
val loginForm = Form("email"->nonEmptyText)
or:
val loginForm = Form("email"->email)
For the later one, if user doesn't input, it will still show Invalid email, which is not what I want.
UPDATE1
I tried Julien's answer:
val loginForm = Form("email" -> (email verifying nonEmpty))
When user inputs nothing, the error message will be:
Valid email required, This field is required
Looks like play combines two error messages of email and nonEmpty together, but this is not exactly what I want. I hope when user not input, the message is only:
This field is required
Not:
Valid email required, This field is required
UPDATE2
I found the reason why it display combined errors is in the helper.twitterBootstrapFieldConstructor.scala.html, there is:
<span class="help-inline">#elements.errors(elements.lang).mkString(",")</span>
It combines all the errors with ,.
For my case, it should be:
<span class="help-inline">#elements.errors(elements.lang).lastOption</span>
Here, lastOption is for nonEmpty.
But I think headOption is better, but:
val loginForm = Form("email" -> (nonEmptyText verifying email))
Doesn't work -- there is no constraint of email, so we have to defined one for myself?

According to the Form documentation, you can add constraints to a mapping using the verifying method. There are a few constraints already defined in the Constraints object. So you can write:
val loginForm = Form("email" -> (email verifying nonEmpty))

Related

Play - Custom validations with custom error message

I am using the Play framework in Scala to develop a small blog website. I currently have a form (successfully) set up for an easy registration of users. This login page just accepts a username (ie. no password yet), verifies that is of the appropriate length and doesn't exist yet, and adds this user to the database (currently still in memory). Length can be verified using just the basic form functionality, however, the uniqueness of this username required me to use custom validations.
Now, this all works, except for the custom error message. When a normal form requirement is not fulfilled, an error message is returned and displayed in the view (eg. "The minimum length is: 5"). I want to display a similar message when the name is not unique. In the first link I provided there is an example of custom validations which seems to have an argument that represents such custom error message for validations you write of your own. However, this does not display in the view, while the others do.
Current validation code:
private val myForm: Form[Account] =
Form(mapping("name" -> text(3, 24))(Account.apply)(Account.unapply).verifying(
"Account is not in the DB.",
fields =>
fields match {
case data: Account => accountExists(data.name).isDefined
}
)
)
Anyone has any ideas?

How to keep the value in a field from the inputPassword helper in the Play framework?

Excuse me if the answer is obvious but whilst I know Java I am very new to Scala, the Play framework and general web app development.
I have taken on a project that has a view where you can set up some database connection details that includes fields such as database name, username, password etc. At present the code uses the Play input helper 'inputText' and so the password field shows the password in plain text. I need to fix this and so have changed it to use the 'inputPassword' helper however whenever I visit this page in my app to edit one of the other fields the password field has not been populated with the password so the user needs to re-enter it in order to save, I do not want to have to do this.
The password populated when it was an inputText helper so I can only assume that there's something in the inputPassword helper that stops the value from populating in the form, maybe it expects the password field to only be used when inputting a new one? Is there a way to override this and have it fill in the on screen form with the password so the user does not have to re-enter in order to change another field on the page?
This is the old version in my view
#inputField(form("password"), '_label -> "Password", '_labelwidth -> "2", 'class -> "form-control", '_type -> "password", '_single -> false)</code>
This is the new version
#inputPassword(form("password"), '_label -> "Password", '_labelwidth -> "2", 'class -> "form-control", '_single -> false, '_type -> "password")
I then have an the templates inputField.scala.html which contains #helper.inputText(field, args:_*) and the inputPassword.scala.html which contains #helper.inputPassword(field, args:_*)
I tried adding 'value -> form("password").value to the parameters in the inputPassword version and whilst this displayed something in stars in the password field the credentials were incorrect so it cannot have been the correct information.
Any help or suggestions are appreciated, even if it is to just understand why inputText populates the field whereas inputPassword does not. The only other way I can think of to do this is possibly to have the password as a separate form on the same page and make it so the password entry is only mandatory when using the page for the initial set up of the database credentials and optional on the edit page.
I don't think it's really necessary to send password values back and forth for security reasons. As an internet user I've never seen form with filled password.
Regarding your case I see two options:
Either separate password change into another form (but this is usually an option if you have more sophisticated password reset process, like two-step verification)
Or apply the following password validation logic on the server: leave the password unchanged if it is empty

Play Framework - how to bind form to a session field

Is there a way I can get some parameters from headers, say cookie (in my case logged in userId), and then apply it to a form so I know who is submitting the ticket?
SupportForm
supportForm:Form[SupportTicket] = Form(mapping(
"question" -> text,
"Priority" -> text
)(SupportTicket.Apply)(SupportTicket.Unapply)
What are the good practises here?
Is request present as an implicit when the call to Apply is made so that I can use it (and is this even a good practise?)
EDIT: One of the issues, ofcourse is someone spoofing if I were to create a hidden field with this value. I could encrypt, but the issue again is to somehow verify and return the form, not sure how this can be done....

Spring binding - dealing with numeric inputs?

I'm dealing with a Webflow application where I may have to submit the current form in order to delete a child record (complex workflow, sorry).
The problem is that if the user enters junk data into the form and then presses the "delete" button, the binding and/or validation will fail and the form will never be submitted.
Hence, if they enter junk data, they cannot delete the record.
What is the preferred way of dealing with users entering "junk" data in web forms, particularly entering non-numeric data in numeric fields? I have a Spring form backing object that looks like this:
public class MyFormInfo implements Serializable {
private String myName;
private Integer myNumber;
}
If the user enters junk in the myName field I can ignore that during validation. However if they enter junk in the myNumber field and the binding fails, I have no good way to trap that and I can't submit the form.
Anybody have a good way to deal with this?
Have a look at this answer as well, but in summary there is no good way to add an error message in the case of type mismatch at conversion time.
The mechanisms available (property editors, converters, bean validation) are not meant to deal with a type mismatch.
The best solution is probably to do the validation on the client side via Javascript via some field mask that only accepts numerics. Then on the server a type mismatch would only occur in case of a bug, so the unhandled error could be acceptable.
For doing this on the server, it's possible to add a String property to the DTO, and apply a bean validation:
#Pattern(regexp = "{A-Za-z0-9}*")
String numericField;
Then via bean validation is possible to add error messages to the page, see this example.
If you want to avoid decimal number input in Integer fields, you can do it like this:
In the HTML-form you can do:
<div class="form-outline">
<input type="number" min=1 max=100 required/>
</div>
In the Java-Form you can do:
#NotNull
#Max(value = 100)
#Min(value = 1)
#NumberFormat
private Integer countOfRooms = null;

Play 2.0 password field constructor: no value attrib?

Not sure if this is a security feature, an oversight, or me missing the ocean for the waves, but wondering why there is no value attribute for the password field constructor
This is not an issue for user signup and other form creation events, but becomes a headache when, for example, a user renewal form does not have the password field filled in (and thus fails validation, which is ironic given that they just logged in in order to be able to renew in the first place ;-))
My workaround has been to set the value attrib manually by supplying it as an extra argument:
#inputPassword(
_form("password"), '_label-> "Password*", 'class-> "required",
'value-> _form("password").value map{Some(_)} getOrElse Some("")
)
would prefer the value attribute included by default, however, as with other input elements. Yes, I can override it, but wondering what the dealy-O is regardless
To me, you shouldn't be able to retrieve the user password in any way, since the password should be encrypted before storing it somewhere.