Custom error message in message.properties - grails

I've got Form domain class and there is typeOfTransaction property. This property is required (blank: false). I want to write custom error message for this property, if the user does not set the value, the message must be appeared.
com.example.domain.form.typeOfTransaction.blank = Type of transaction required
Above is the message, but I don't get it when I'm trying to save form with empty typeOfTransaction field. Instead of this message I've got default message
"Please select an item in the list."
p.s. I don't know where this default message is defined.

If you use the absolute name of your class you need to use the exact name of the class, including capitalization - so I'm guessing you should put:
com.example.domain.Form.typeOfTransaction.blank = Type of transaction required
If you don't use the absolute name you don't capitalize the class name:
form.typeOfTransaction.blank = Type of transaction required

Well, for 1.3.7 it should be in grails-app/i18n/messages.properties (or one of the language specific variants if appropriate). I assume 2.0 would use the same location.

Related

Puzzling validation error after upgrading from Grails 2.2.5 to 4.0.11

A method which was working for a long time in Grails 2.2.5 has broken after moving to 4.0.11 with a validation error on saving, and the error is a puzzle to me. I have a domain class 'Decline' which has one of its properties 'user', which is of domain class user. As part of the save process I assign the currently logged in user to this property:
Decline decline = new Decline()
decline.policy = policy
decline.declineTime = new Date()
decline.field = field
decline.cause = reason
decline.user = User.getUser()
decline.save(flush:true)
This was working fine in 2.2.5 but now I get the following validation error:
Field error in object 'myapp.pei.Decline' on field 'user.userType': rejected value [DIRECT_CLIENT]; codes [myapp.User.userType.nullable.error.myapp.pei.Decline.user.userType,myapp.User.userType.nullable.error.user.userType,myapp.User.userType.nullable.error.userType,myapp.User.userType.nullable.error.myapp.UserType,myapp.User.userType.nullable.error,user.userType.nullable.error.myapp.pei.Decline.user.userType,user.userType.nullable.error.user.userType,user.userType.nullable.error.userType,user.userType.nullable.error.myapp.UserType,user.userType.nullable.error,myapp.User.userType.nullable.myapp.pei.Decline.user.userType,myapp.User.userType.nullable.user.userType,myapp.User.userType.nullable.userType,myapp.User.userType.nullable.myapp.UserType,myapp.User.userType.nullable,user.userType.nullable.myapp.pei.Decline.user.userType,user.userType.nullable.user.userType,user.userType.nullable.userType,user.userType.nullable.myapp.UserType,user.userType.nullable,nullable.myapp.pei.Decline.user.userType,nullable.user.userType,nullable.userType,nullable.myapp.UserType,nullable]; arguments [userType,class myapp.User]; default message [Property [{0}] of class [{1}] cannot be null]
There are two things which are puzzling about this. Firstly, and more importantly, this appears to be an error saving the User object. But why is it even trying to save the User object? I have assigned an existing User object which it should be using. Secondly, the specific error is 'rejected value [DIRECT_CLIENT]' for field 'user.userType', but the error message is that this field cannot be null. So it's rejecting a value but telling me it cannot be null! The value, incidentally, is of a UserType enum defined thus:
public enum UserType {
ADMIN_USER,ADMIN_OWNER_USER,SUPER_USER,BROKER,DIRECT_CLIENT
}
I wonder what change from version 2.2.5 to 4 (or maybe 3) could have caused this?
It seems there was some change in behaviour of deepValidate between Grails 2.x and 4.x which is causing this, although I don't see why validation of the associated User object should be failing when it can actually be saved OK separately. But what got me past this issue was to set the following in the mapping block for Decline:
user cascadeValidate: 'none'
This ensures that when the Decline object is saved it does not attempt to validate the User as well.

Not able to set WorkItem State using TFS API?

I am trying to set State property value of Test Case Work item. I am creating using TFS API and C# code.
It throws an error while I save the test case using Save() method. I have called the Validate() method of a work item and the ArrayList shows the value I am trying to assign is an invalid state.
testCase.State = TestPointState.Ready.ToString();
ArrayList result = testCase.WorkItem.Validate();
if (!testCase.WorkItem.IsValid())
{
//this block executes
}
When I manually opened the MTM to see what are the different STATE values for existing work items, then I found READY and DESIGN. That's why I tried t assign TestPointState.Ready enum. I tried assiging READY string directly in that statement, but still the same exception whlie saving the test case.
Any idea on how to fix this issue ?
It is possible that when setting the state another field has then an invalid input. e.g.: when you change from Ready to Design it might require that you select who the AssignTo person is and so you'll need to populate these fields as well. You can use the Validate method to get a list of invalid fields after you set the state like below.
ArrayList invalidFields = newWI.Validate();

Grails domain custom error messages

I am working in a grails application, I have many domains in the applications, more than 50! The error message generated are default, I have the following in my message.properties file
default.blank.message=Field "{0}" cannot be blank.
An example of my one of the domain class is as follows:
class Person {
String firstName;
String lastName;
String middleName;
Date dob;
String gender;
String religion;
String nationality;
String maritalStatus;
Zone permAddZone;
District permAddDistrict;
String permAddVDC;
}
And so on, so when I leave a field, for example 'maritalStatus' the following error message shows up, 'Field "maritialStatus" cannot be blank.'. I also added the following to my message.properties file
person.maritialStatus=Maritial Status
But still I am getting the 'Field "maritialStatus" cannot be blank.' message. I also tried using I18n Templates Plugin, but as I have a lot of domain classes, modifying error message for all of them would be time consuming. So, what choices do I have or what am I doing wrong. Any help is appreciated.
The appropriate message key to override is specified on the reference page for each constraint type. In the case of blank it's
com.example.Person.maritalStatus.blank=Marital status must not be blank
However this will be very time consuming and repetitive if you have many domains and many properties.
What you are asking for is instead a way to process the domain class property names in some way before they are inserted into the default messages. This isn't something Grails supports out of the box but I like a challenge... and I've found a surprisingly elegant way to implement it. My approach is the grails plugin available at https://github.com/ianroberts/recursive-messages and it works by extending the format string syntax to support placeholders of the form
default.blank.message=Field "{0,message,field.name.}" cannot be blank.
A placeholder {N,message,prefix} is resolved by prepending the given prefix to the usual placeholder replacement value and then treating the resulting string (field.name.maritalStatus in this example) as a no-argument message key, and looking that up in the usual way. Thus you could have different representations for different languages.
It has to be a plugin because it relies on a trick that works in a plugin's doWithSpring but doesn't work in an application's resources.groovy, to modify the definition of the default messageSource Spring bean.
Disclaimer: this was a quick fix, it hasn't been fully tested and could probably be implemented more efficiently.
In order to override the field label you need to override the key:
<package>.<domainclass>.<fieldname>.label
So in your case, try:
<package>.Person.martialStatus.label=Label

Where is the Magic in the Validation?

In my RazorView i use:
#Html.Editor(prop.PropertyName)
to get the EditorForm. It also creates the Tags: data-val-* with Validationmessages. But in this auto generated Validationmessages the variablename is shown as type.
data-val-number="The field "Int32" must be numeric."
I think this is because the object that cames to the Validationfunction misses the variablename and so he uses the type. So I need to know where the function tries to get the variablenname or which field the function tries to read to fix this.
p.s.
I realy donĀ“t want to change my previous code to fix this, it has his reasons why it is like it is ;-)
The variable name will default to the Property name unless you add a [DisplayName("New Name")] attribute to the Property to change the name used. What type is prop in your example?

Grails Problem with custom error messages

I am currently trying to specify custom error messages in grails for the default constraints but so far all I get back is the default error message.
I know that I have to edit the grails-app/i18n/messages.properties file
If I change the following default error codes message, it will correctly display the new error message
default.blank.message=Property [{0}] of class [{1}] cannot be blank
However, this is not what I am trying to do. I need more granular error reporting and have more than one field that can be blank etc. What I would like to be able to do would be, display custom messages for each field in a class
package com.mycompany.myapp
class Test{
String name
def constraints = {
name(nullable:false, blank:false)
}
}
(following codes appended to end of messages.properties)
test.name.blank=Name cannot be blank
test.name.nullable=Name cannot be nullable
According to the grails documentation this should work correctly, either with or without the package name - className.propertyName.blank
grails.org/doc/latest/ (constraints section) & (section 7.4 - validation & internationalization)
I have tried all comnbinations that I can think of, but it always displays the custom message
I have also tried installing the grails i18n templates plugin
http://www.grails.org/I18n+Templates+Plugin
which generated the error codes automatically for me. I appended the new error codes to the end of the existing messages.properties file but I still get the default error messages.
However, there was something different with the error codes that were generated by the plugin.
instead of the format specified in the grails doc - test.name.null=......, it automatically generated test.name.null.error=Custom Message
I have also tried deleting the default error messages completely, but they are still displayed
If anyone has experienced this issue before, I would appreciate any help that anyone can give me
Thanks in advance
put def messageSource (in controller or service)
item.errors?.allErrors?.each{
println messageSource.getMessage(it, null)
};
I also found a good link which explains this better
http://johnrellis.blogspot.com/2010/02/retrieve-grails-domain-errors-from.html
Well, the documentation shows you an example of how to override the messages for one of the default Validation Constraints (blank, nullable, min, max, size, range, etc.). But it fails to tell you to look in the documentation for each Constraint and at the bottom it shows you what propery key to use:
Error Code: className.propertyName.size.toosmall or className.propertyName.size.toobig
for Constraint size http://grails.org/doc/latest/ref/Constraints/size.html
So, for
package com.example
class User {
String username
static constraints = {
username size:5..15
}
}
use:
com.example.User.username.size.toosmall=Yo there! too small: [{0}] of class [{1}] with value [{2}] does not fall within the valid size range from [{3}] to [{4}]
com.example.User.username.size.toobig=Yo there! too big: [{0}] of class [{1}] with value [{2}] does not fall within the valid size range from [{3}] to [{4}]
It might be that your constraints aren't static - it should be specified as "static constraints = { ..."
Also note that nullable defaults to false so you don't need to specify that.
I use fully qualified class names in my messages.properties
com.shareyourlove.User.password.blank=Some custom message
This worked for me
com.model.Customer.name.nullable.error = Custom message
instead of
com.model.Customer.name.blank = Custom message

Resources