I have a problem when I use grail automatic databinding "ex: Test t = new Test(params)" with decimal delimiter on Double form field. After few search, I've found that it is relative to the browser Locale.
Example : If I enter number with decimals separated by a dot '3.45' it does not work (The decimal part of the number is ignored). It store 3.0 in my database
If I do the same test but using a comma '3,45' for decimal separator, everything works fine. Grails store 3.45 in the database.
The problem is that nobody enter number with comma delimiter. (even the numpad enter a dot '.' when set to fr_CA)
I've already found some solutions like register custom number editor (bit painful when you have many apps) or set the global localeResolver to en_US (that last one doesn't do the job because I loose all the internationalization functionality of my app).
So, does someone have an easy solution to fix that problem?
using: Grails : 2.2.0 Browser : Google Chrome (locale fr_CA)
Thanks a lot!
I've been searching and trying for 2 days. I've finally chosen to define a custom PropertyEditorRegistar. This way, I can fix the Locale only for the Double field format. However, I don't think that it's the best solution because it will be applied to all my Double fields. But in the mean time it does the job pretty well. So if someone have a better solution, I will be glad to test it and update my code.
So this is how I set this up :
1 - Create a new groovy class that implements PropertyEditorRegistrar (if you already have one, just add the part of code contained by the method in the existing one)
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.beans.PropertyEditorRegistrar;
import org.springframework.beans.PropertyEditorRegistry;
import org.springframework.beans.propertyeditors.CustomNumberEditor;
public class CustomDoubleRegistrar implements PropertyEditorRegistrar {
@Override
public void registerCustomEditors(PropertyEditorRegistry registry) {
//define new Double format with hardcoded Locale.ENGLISH
registry.registerCustomEditor(Double.class,
new CustomNumberEditor(Double.class,
DecimalFormat.getInstance(Locale.ENGLISH),true))
}
}
2- Define the custom registrar into the conf/spring/resources.goovy (if it's not already there of course)
beans = {
customPropertyEditorRegistrar(CustomDoubleRegistrar)
}
3- That's it, the Grails auto data binding will work fine
Test t = new Test(params);
//params contains many Double fields with dot '.' as decimal delimiter
Don't hesitate to post better solutions... Thanks
EDIT 1
Since Grails 2.3 this solution is no longer working. If you still want to use this solution, you have to add this configuration to the Config.groovy file
grails.databinding.useSpringBinder = true
Or implement one of the new DataBinding. I've tried few of them but nothing seems to solve the decimal delimiter issue. Thank you to post answer if you know how...
EDIT 2
Since Grails 2.4+ you can define your own ValueConverter to bypass the basic Locale validation. Note that you must remove the changes made in the initial post and in the EDIT 1. Here's how to implement the custom ValueConverter:
conf/spring/resources.groovy
// Place your Spring DSL code here
beans = {
"defaultGrailsjava.lang.DoubleConverter"(DoubleValueConverter)
}
class DoubleValueConverter implements ValueConverter {
public LongValueConverter() {
}
boolean canConvert(value) {
value instanceof Double
}
def convert(value) {
//In my case returning the same value did the trick but you can define
//custom code that takes care about comma and point delimiter...
return value
}
Class<?> getTargetType() {
return Double.class
}
}
For Grails 2.3+ you can properly override the default binder/converter, although it is not trivial or intuitive.
See my answer here: Binding real number values to Grails domain attributes (values sent by Dojo widgets)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With