2010-01-21 10 views
5

Ho un campo nel mio oggetto di dominio che io definisco come un intero ...Come posso modificare il modo in cui GRAILS GSP fieldValue formats Integers?

Integer minPrice 

Ho poi accedere in una pagina SPG come segue:

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

e quello che ho nel mio HTML è ...

100,000 

che non è un numero intero, è una stringa. Peggio ancora, è una stringa formattata in un particolare locale.

Questo è un problema perché ho un controllo SELECT su un FORM HTML che ha un intervallo (non ordinale) di valori per minPrice che voglio memorizzare nel mio oggetto dominio come numeri interi, e non voglio memorizza un indice su una serie di valori che devo mappare ripetutamente avanti e indietro, voglio il valore stesso.

mio controllo di selezione si presenta così ...

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

Quando ottengo il valore dal campo SELECT per inviare al server ha correttamente un valore intero, che io insisto. Tuttavia, il viaggio di ritorno non seleziona mai la riga corretta nel menu a discesa perché il valore è una stringa separata da virgole.

Questo funziona bene altrove nel mio codice per i piccoli numeri in cui la formattazione della virgola non entra in gioco, e il round-trip dentro e fuori il SELECT ha successo. Ma i valori> 999 non funzionano.

I documenti dicono "Questo tag ispezionare un fagiolo che è stata oggetto di associazione dati e ottenere il valore del campo sia dal valore originariamente presentato contenuta all'interno errori del bean dell'oggetto popolamento durante associazione dei dati oppure dal valore della proprietà di un bean. Una volta ottenuto il valore, verrà automaticamente codificato in HTML. "

È l'ultimo bit che voglio evitare in quanto sembra formattare gli interi. Quindi, quale piccola parte della magia Grails/GSP devo conoscere per poter ottenere il mio intero da rendere come intero nella mia SELECT e preselezionare la riga giusta?

EDIT: Ho provato alcune cose ulteriormente sulla base delle risposte di seguito, con risultati piuttosto deludenti finora ...

Se metto il tag <gformatNumber/> nel mio <g:select/> ottengo il codice della pagina come testo nel 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" 
/> 

Utilizzando il tag formato numerico da GSP sul mio valore intero di 100000 come questo ...

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

100. Ricorda che il fieldValue restituisce 100,000, quindi questa non è una sorpresa.

Se uso il taglib jsp come questo ...

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

ottengo un errore dalla pagina compilatore Cannot format given Object as a Number.

Credo di avere un problema più ampio di quello che non riesco a ottenere un valore intero come un intero vero e proprio nel mio codice, se è superiore a 999 a causa del default (e non configurabile) il comportamento della direttiva fieldValue. Tuttavia il mio problema specifico di non essere in grado di preselezionare un valore intero in un controllo SELECT non sta andando via. Al momento sono un po 'in perdita.

Chiunque ha altre idee?

risposta

5

Penso che tu abbia almeno due soluzioni possibili.

Uno è quello di utilizzare la taglib JSTL come descritto nel docs.

Un altro modo più interessante è utilizzare il tag "formatNumber" incluso in Grails - anche nello docs.

per il vostro scopo, l'uso di tag che potrebbe assomigliare a questo:

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

Non riesco a far funzionare nessuna di queste soluzioni ... vedi modifica sopra. In retrospettiva è ovvio, se fosse semplicemente Java non avrei bisogno di un formattatore di numeri, avrei bisogno di Integer.parseInt() per ottenere il risultato da fieldValue nel tipo giusto. Questo non può essere così difficile ... cosa sto sbagliando? – Simon

0

Ho un/lavoro-tutto l'soluzione ... La risposta sembra essere: "non fare nulla".

Invece di cercare di analizzare il numero di stringata di nuovo in un intero, ho lasciato come una stringa formattata ai fini della selezione. Questo mi ha costretto a cambiare i miei from valori come segue:

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

Naturalmente, quando ho posto al server il valore che viene inviato è "100000" come stringa di escape. Quello che ho capito è che Grails, Spring, o Hibernate, o qualcosa nello stack, farebbe tornare la Coerenza della String nel giusto tipo Integer prima della persistenza.

Questo funziona bene per i miei scopi, ma penso che è fondamentalmente un lavoro di tutto piuttosto che una soluzione a causa di problemi di locale. Se il mio migliaio separatore è un "." e il mio separatore decimale è ",", che è per gran parte dell'Europa, quindi il mio codice non funzionerà.

3

Migliore utilizzo custom PropertyEditor per non disturbare con il tag formatNumber ogni volta che si emette un valore. Come, dichiarare un fagiolo in resources.groovy:

myOwnCustomEditorRegistrar(CustomEditorRegistrar) 

e creare la classe:

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

vedi anche l'ultimo commento in questa pagina http://grails.1312388.n4.nabble.com/Changing-Number-Formating-td1379022.html – 10GritSandpaper

7

Vuoi visualizza il numero di crudo? come 100000?

È possibile ottenere il campo direttamente:

${myBean.minPrice} 
+0

Ti darei 10 voti se potessi. Semplice è sempre il migliore –

+3

se lo si visualizza direttamente usando $ {bean.value} - si perde la possibilità di visualizzare valori che non hanno superato la validazione! –

1

Change

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

a

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

Utilizzare l'attributo 'groupingUsed' in combinazione con il formato:

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

Ho trovato che il modo migliore per gestire questo è stato quello che ha fatto Victor Sergienko (alzato tra parentesi) con l'uso di un PropertyEditor.

Creare un editor per intero, messo in src/Groovy:

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

    public String getAsText() { 
     value 
    } 
} 

e registrarlo utilizzando un PropertyEditorRegistrar (anche in src/Groovy):

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

aggiungere il registrar fino a primavera config (graal-app/conf/primavera/resource.groovy):

beans = { 
    customEditorRegistrar(MyEditorRegistrar) 
} 

Da ora in poi qualsiasi Integ i nomi che sono vincolati, ricevono errori (o non) e poi vengono nuovamente visualizzati con il tag fieldValue devono essere visualizzati dal valore predefinito di Integer - è possibile personalizzare questo comportamento nell'editor modificando l'implementazione getAsText.

Personalmente creerei un wrapper per questo tipo di cose in modo da poter impostare un editor solo per quel tipo piuttosto che su tutta la linea per un tipo usato frequentemente. Anche se mi rendo conto che ciò significherebbe un po 'di mappatura quando persistono nel DB ...

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