如何更改GRAILS GSP fieldValue格式化整数的方式?

时间:2010-01-21 09:59:43

标签: grails gsp

我的域对象中有一个字段,我将其定义为整数...

Integer minPrice

然后我在GSP页面中访问它,如下所示:

${fieldValue(bean: myBean, field: 'minPrice')}

我在HTML中得到的是......

100,000

不是整数,它是一个字符串。更糟糕的是,它是特定语言环境中的格式化字符串。

这是一个问题,因为我在HTML FORM上有一个SELECT控件,它有一个minPrice的(非序数)值范围,我希望将它作为整数存储在我的域对象中,我不想存储我必须在它们之间反复映射的某些值数组的索引,我想要值本身。

我的选择控件看起来像这样......

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

当我从SELECT字段获取值以回发到服务器时,它正确地具有一个Integer值,我坚持这个值。但是,返回行程从不预先选择下拉列表中的右行,因为该值是以逗号分隔的字符串。

这在我的代码中的其他地方可以很好地用于小数字,其中逗号格式化不起作用,并且SELECT的往返行程成功。但是值> 999不起作用。

文档说“此标记将检查已成为数据绑定主题的bean,并从数据绑定期间填充的bean的errors对象中包含的最初提交的值中获取字段的值,或者从bean的属性值。一旦获得该值,它将自动进行HTML编码。“

这是我想要避免的最后一点,因为它似乎格式化整数。那么,我需要知道什么样的Grails / GSP魔法,这样我可以将我的整数渲染为一个整数到我的SELECT并预先选择正确的行?

修改 我根据下面的答案尝试了一些其他的东西,到目前为止结果非常令人失望......

如果我将<gformatNumber/>标记放在我的<g:select/>中,我会在浏览器中将页面代码作为文本。

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

使用GSP中的数字格式标签对我的整数值100000这样......

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

给出100。请记住,fieldValue会回复100,000,所以这并不奇怪。

如果我像这样使用jsp taglib ......

<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
var y = <fmt:formatNumber value="${fieldValue(bean: personInstance, field: 'minPrice')}" pattern=".00"/>;

我从页面编译器Cannot format given Object as a Number收到错误。

由于fieldValue指令的默认(和不可配置)行为,如果它大于999,我想我有一个更广泛的关注点似乎无法将Integer值作为真正的整数获取到我的代码中。但是,我无法在SELECT控件中预先选择Integer值的具体问题不会消失。目前我有点失落。

任何人都有任何进一步的想法吗?

8 个答案:

答案 0 :(得分:8)

您想显示原始数字吗?像100000?

您可以直接获取该字段:

${myBean.minPrice}

答案 1 :(得分:5)

我认为你至少有两种可能的解决方案。

一种是使用docs中描述的JSTL标记库。

另一种更酷的方法是使用grails中包含的'formatNumber'标记 - 也在docs中。

出于您的目的,该标记的使用可能如下所示:

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

答案 2 :(得分:3)

更好地使用custom PropertyEditor,以便每次输出值时都不会打扰formatNumber标记。 比如,在resources.groovy中声明一个bean:

myOwnCustomEditorRegistrar(CustomEditorRegistrar)

创建你的课程:

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

答案 3 :(得分:3)

将'groupingUsed'属性与您的格式结合使用:

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

答案 4 :(得分:1)

更改

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

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

答案 5 :(得分:1)

我发现解决这个问题的最好方法就是使用PropertyEditor做Victor Sergienko(up up btw)所暗示的。

为Integer创建一个编辑器,放入src / groovy:

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

    public String getAsText() {
        value
    }
}

使用PropertyEditorRegistrar(也在src / groovy中)注册它:

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

将您的注册商添加到spring配置中(grails-app / conf / spring / resource.groovy):

beans = {
    customEditorRegistrar(MyEditorRegistrar)
}

从现在起,绑定的任何整数,接收错误(或不接收)然后使用fieldValue标记重新显示应该由Integer的默认toString显示 - 您可以通过修改getAsText实现在编辑器中自定义此行为。

就个人而言,我会为这种事情创建一个包装器,这样你就可以为这种类型设置一个编辑器,而不是为了常用类型而设置一个编辑器。虽然我意识到这将意味着在持久保存到数据库时会有一些映射......

答案 6 :(得分:0)

我有一个解决方案/工作轮...答案似乎是“什么也不做”。

我没有尝试将字符串化的数字解析为整数,而是将其保留为格式化字符串以用于选择。这意味着我必须按如下方式更改from值:

<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"
/>

当然,当我回发到服务器时,发送的值是“100,000”作为转义字符串。我意识到Grails,Spring或者Hibernate,或者堆栈中的东西,会在持久化之前将String的版本重新转换为正确的Integer类型。

这对我的目的来说很好,但是我认为它基本上是一个工作循环而不是解决方案,因为区域设置问题。如果我的千分隔符是“。”我的小数点分隔符是“,”,它适用于欧洲大部分地区,那么我的代码将不起作用。

答案 7 :(得分:0)

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