How can I change the way GRAILS GSP fieldValue formats Integers?

|▌冷眼眸甩不掉的悲伤 提交于 2019-11-29 02:31:31

Do you want to show the raw number? like 100000?

You can get the field directly:

${myBean.minPrice}

I think you have at least two possible solutions.

One is to use the JSTL taglib as described in the docs.

Another, cooler way is to use the 'formatNumber' tag included with grails - also in the docs.

For your purpose, the use of that tag might look like this:

<g:formatNumber number="${fieldValue(bean: myBean, field: 'minPrice')}" format="######" />

Use the 'groupingUsed' attribute in combination with your format:

<g:formatNumber number="${fieldValue(bean: personInstance, field: 'minPrice')}" 
                format="#" 
                groupingUsed="true" />

Better use custom PropertyEditor in order not to bother with formatNumber tag every time you output a value. Like, declare a bean in resources.groovy:

myOwnCustomEditorRegistrar(CustomEditorRegistrar)

And create your class:

class CustomEditorRegistrar implements PropertyEditorRegistrar {
    void registerCustomEditors(PropertyEditorRegistry registry) {
        registry.registerCustomEditor(BigDecimal.class, new MyBigDecimalEditor(BigDecimal.class))
    }
}

Change

var x = <g:formatNumber number="${fieldValue(bean: personInstance, field: 'minPrice')}" format="#" />;

to

var x = <g:formatNumber number="${personInstance.minPrice}" format="#" />;

I found the best way to handle this was doing what Victor Sergienko (upped btw) hinted at with using a PropertyEditor.

Create an editor for Integer, put in src/groovy:

class IntegerEditor extends PropertyEditorSupport {
    void setAsText(String s) {
        if (s) value = s as Integer
    }

    public String getAsText() {
        value
    }
}

and register it using a PropertyEditorRegistrar (also in src/groovy):

class MyEditorRegistrar implements PropertyEditorRegistrar {
    public void registerCustomEditors(PropertyEditorRegistry reg) {
        reg.registerCustomEditor(Integer, new IntegerEditor())
    }
}

add your registrar into the spring config (grails-app/conf/spring/resource.groovy):

beans = {
    customEditorRegistrar(MyEditorRegistrar)
}

From now on any Integers that are bound, receive errors (or not) and then redisplayed with the fieldValue tag should be displayed by Integer's default toString - you can customise this behaviour in the editor by amending the getAsText implementation.

Personally I would create a wrapper for this kind of thing so you can set up an editor just for that type rather than across the board for a frequently used type. Though I realise this would mean a little bit of mapping when persisting to the DB...

I have a solution/work-round... The answer seems to be, "do nothing".

Instead of trying to parse the stringified number back into an integer, I left it as a formatted string for the purposes of the select. This meant I had to change my from values as follows:

<g:select name="minPrice" 
value="${fieldValue(bean: personInstance, field: 'minPrice')}"  
onchange="setDirty()"
noSelection='${['0':'Select a number...']}'
from="${[
    ['name':'100,000', 'id':'100,000'],
    ['name':'200,000', 'id':'200,000'],
    ['name':'300,000', 'id':'300,000']
    ]}"
optionKey="id" optionValue="name"
/>

Of course when I post back to the server the value that gets sent is "100,000" as an escaped String. What I realised was that Grails, or Spring, or Hibernate, or something in the stack, would do the coersion of the String back into the right Integer type prior to persistence.

This works just fine for my purposes, however I think it is basically a work-round rather than a solution because of locale issues. If my thousand separator is a "." and my decimal separator is ",", which it is for much of Europe, then my code won't work.

Use like this :
<g:formatNumber number="${fieldValue(bean: personInstance, field: 'minPrice')}"
 format="#.##"/>;
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!