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

发布于 2024-08-18 10:33:57 字数 2457 浏览 6 评论 0原文

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

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 字段获取值以回发到服务器时,它正确地具有一个整数值,我坚持该值。但是,回程永远不会在下拉列表中预先选择正确的行,因为该值是此逗号分隔的字符串。

这在我的代码中的其他地方工作得很好,对于逗号格式不起作用的小数字,并且 SELECT 的往返进出是成功的。但值 >999 不起作用。

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

这是我想要避免的最后一点,因为它似乎格式化了整数。那么,我需要了解哪些 Grails/GSP 魔法才能将我的 Integer 作为整数呈现到我的 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"
/>

在我的整数值 100000 上使用 GSP 的数字格式标签,如下所示...

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

我会从页面编译器中收到错误无法将给定对象格式化为数字

我想我有一个更广泛的担忧,如果由于 fieldValue 指令的默认(且不可配置)行为,如果整数值大于 999,我似乎无法将其作为真正的整数获取到我的代码中。然而,我无法在 SELECT 控件中预先选择整数值的具体问题并没有消失。此刻我有点不知所措。

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

I have a field in my domain object which I define as an Integer...

Integer minPrice

I then access it in a GSP page as follows:

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

and what I get in my HTML is...

100,000

which is not an Integer, it's a String. Worse still it's a formatted String in a particular locale.

This is a problem because I have a SELECT control on an HTML FORM which has a (non-ordinal) range of values for minPrice which I want to store in my domain object as integers, and I don't want to store an index to some array of values that I have to repeatedly map back and forth between, I want the value itself.

My select control looks like this...

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

When I get the value from the SELECT field to post back to the server it correctly has an Integer value, which I persist. However the return trip never pre-selects the right row in the drop-down because the value is this comma separated String.

This works fine elsewhere in my code for small numbers where the comma formatting doesn't come into play, and the round-trip in and out of the SELECT is successful. But values >999 don't work.

The docs say "This tag will inspect a bean which has been the subject of data binding and obtain the value of the field either from the originally submitted value contained within the bean's errors object populating during data binding or from the value of a bean's property. Once the value is obtained it will be automatically HTML encoded."

It's that last bit that I want to avoid as it appears to format Integers. So, what little bit of Grails/GSP magic do I need to know so I can get my Integer to be rendered as an integer into my SELECT and pre-select the right row?

EDIT:
I have tried some further things based on the answers below, with pretty disappointing results so far...

If I put the <gformatNumber/> tag in my <g:select/> I get the page code as text in the browser.

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

Using the number format tag from GSP on my Integer value of 100000 like this...

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

gives 100. Remember that the fieldValue gives back 100,000, so this is not a surprise.

If I use the jsp taglib like this...

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

I get an error from the page compiler Cannot format given Object as a Number.

I guess I have a wider concern than I can't seem to get an Integer value as a genuine integer into my code if it is greater than 999 because of the default (and unconfigurable) behaviour of the fieldValue directive. However my specific problem of not being able to pre-select an Integer value in a SELECT control is not going away. At the moment I'm at a bit of a loss.

Anyone have any further ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

心凉怎暖 2024-08-25 10:33:57

您想显示原始数字吗?比如100000?

您可以直接获取该字段:

${myBean.minPrice}

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

You can get the field directly:

${myBean.minPrice}
早茶月光 2024-08-25 10:33:57

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

一种是使用 JSTL 标记库,如 文档

另一种更酷的方法是使用 grails 中包含的“formatNumber”标签 - 也在 文档

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

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

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="######" />
财迷小姐 2024-08-25 10:33:57

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

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

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

<g:formatNumber number="${fieldValue(bean: personInstance, field: 'minPrice')}" 
                format="#" 
                groupingUsed="true" />
撑一把青伞 2024-08-25 10:33:57

最好使用自定义PropertyEditor,以免打扰formatNumber 每次输出值时标记。
比如,在 resources.groovy 中声明一个 bean:

myOwnCustomEditorRegistrar(CustomEditorRegistrar)

并创建你的类:

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

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))
    }
}
最后的乘客 2024-08-25 10:33:57

更改

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

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

Change

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

to

var x = <g:formatNumber number="${personInstance.minPrice}" format="#" />;
蓝天白云 2024-08-25 10:33:57

我发现处理这个问题的最佳方法是使用 Victor Sergienko(顺便说一句)暗示的使用 PropertyEditor。

为 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 实现在编辑器中自定义此行为。

就我个人而言,我会为这种事情创建一个包装器,这样您就可以只为该类型设置一个编辑器,而不是为经常使用的类型全面设置。虽然我意识到这意味着在持久化到数据库时需要进行一些映射......

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...

泛滥成性 2024-08-25 10:33:57

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

我没有尝试将字符串化的数字解析回整数,而是将其保留为格式化字符串以供选择之用。这意味着我必须更改我的 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 类型。

这对于我的目的来说效果很好,但我认为由于区域设置问题,这基本上是一个解决方案,而不是一个解决方案。如果我的千位分隔符是“.”我的小数点分隔符是“,”,这对于欧洲大部分地区来说都是如此,那么我的代码将无法工作。

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.

时光礼记 2024-08-25 10:33:57
Use like this :
<g:formatNumber number="${fieldValue(bean: personInstance, field: 'minPrice')}"
 format="#.##"/>;
Use like this :
<g:formatNumber number="${fieldValue(bean: personInstance, field: 'minPrice')}"
 format="#.##"/>;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文