XIII. Exemple 10 - Conversion et validation des nombres réels▲
La nouvelle application présente la saisie des nombres réels :
- en [1], le formulaire de saisie
- en [2], la réponse renvoyée
L'application a un fonctionnement similaire à celui de la saisie des nombres entiers aussi ne commenterons-nous que les points qui diffèrent.
XIII-A. Le projet Netbeans▲
Le projet Netbeans est le suivant :
- en [1], les vues de l'application
- [Accueil.jsp] : la page d'accueil
- [FormDouble.jsp] : le formulaire de saisie
- [ConfirmationDouble.jsp] : la page de confirmation
- en [2], le fichier des messages [messages.properties] et le fichier de configuration principal de Struts
- en [3] :
- [FormDouble.java] : l'action qui affiche et traite le formulaire
- [FormDouble-validation.xml] : les règles de validation de l'action [FormDouble]. Ce fichier délègue ces validation au modèle selon la méthode qui vient d'être vue.
- [FormDoubleModel] : le modèle de l'action [FormDouble]
- [FormDoubleModel-validation.xml] : les règles de validation du modèle
- [FormDoubleModel.properties] : le fichier des messages du modèle
- [example.xml] : fichier de configuration secondaire de Struts
XIII-B. La configuration du projet▲
Le projet est principalement configuré par le fichier [example.xml] suivant :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd"
>
<struts>
<package
name
=
"example"
namespace
=
"/example"
extends
=
"struts-default"
>
<action
name
=
"Accueil"
>
<result
name
=
"success"
>
/example/Accueil.jsp</result>
</action>
<action
name
=
"FormDouble"
class
=
"example.FormDouble"
>
<result
name
=
"input"
>
/example/FormDouble.jsp</result>
<result
name
=
"cancel"
type
=
"redirect"
>
/example/Accueil.jsp</result>
<result
name
=
"success"
>
/example/ConfirmationFormDouble.jsp</result>
</action>
</package>
</struts>
Il est analogue à celui qui a été étudié pour la saisie des nombres entiers.
XIII-C. Les fichiers des messages▲
Le fichier [messages.properties] est le suivant :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
Accueil.titre=Accueil
Accueil.message=Struts 2 - Conversions et validations
Accueil.FormDouble=Saisie de nombres r\u00e9els
Form.titre=Conversions et validations
FormDouble.message=Struts 2 - Conversion et validation de nombres r\u00e9els
FormDouble.conseil=Tapez les nombres r\u00e9els avec une virgule comme 10,7
Form.submitText=Valider
Form.cancelText=Annuler
Form.clearModel=Raz mod\u00e8le
Confirmation.titre=Confirmation
Confirmation.message=Confirmation des valeurs saisies
Confirmation.champ=champ
Confirmation.valeur=valeur
Confirmation.lien=Formulaire de test
xwork.default.invalid.fieldvalue=Valeur invalide pour le champ "{0}".
Le fichier [FormDoubleModel.properties] est le suivant :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
double.format={0,number}
double1.prompt=1-Nombre r\u00E9el
double1.error=Tapez un nombre r\u00E9el
double2.prompt=2-Nombre r\u00E9el
double2.error=Tapez un nombre r\u00E9el
double3.prompt=3-Nombre r\u00E9el >=2.64
double3.error=Tapez un nombre r\u00E9el >=2.64
double4.prompt=4-Nombre r\u00E9el <8.32
double4.error=Tapez un nombre r\u00E9el <8.32
double5.prompt=5-Nombre r\u00E9el dans l''intervalle [2.64,8.32[
double5.error=Tapez un nombre r\u00E9el dans l''intervalle [2.64,8.32[
double6.prompt=6-Nombre r\u00E9el dans l''intervalle [2.64,8.32]
double6.error=Tapez un nombre r\u00E9el dans l''intervalle [2.64,8.32]
La ligne 1 joue un rôle important. Nous y reviendrons.
XIII-D. Le formulaire de saisie▲
La vue [FormDouble.jsp] est la suivante :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
<%@
page
contentType
=
"text/html; charset=UTF-8"
pageEncoding=
"UTF-8"
%>
<%@
taglib
prefix
=
"s"
uri
=
"/struts-tags"
%>
<html>
<head>
<title><s
:
text
name=
"Form.titre"
/></title>
<s
:
head
/>
</head>
<body background=
"<s:url value="
/ressources/standard.jpg
"/>"
>
<h2><s
:
text
name=
"FormDouble.message"
/></h2>
<h4><s
:
text
name=
"FormDouble.conseil"
/></h4>
<s
:
form
name=
"formulaire"
action=
"FormDouble"
>
<s
:
textfield
name=
"double1"
key=
"double1.prompt"
/>
<s
:
textfield
name=
"double2"
key=
"double2.prompt"
value=
"%{#parameters['double2']!=null ? #parameters['double2'] : double2==null ? '' :getText('double.format',{double2})}"
/>
<s
:
textfield
name=
"double3"
key=
"double3.prompt"
value=
"%{#parameters['double3']!=null ? #parameters['double3'] : double3==null ? '' :getText('double.format',{double3})}"
/>
<s
:
textfield
name=
"double4"
key=
"double4.prompt"
value=
"%{#parameters['double4']!=null ? #parameters['double4'] : double4==null ? '' :getText('double.format',{double4})}"
/>
<s
:
textfield
name=
"double5"
key=
"double5.prompt"
value=
"%{#parameters['double5']!=null ? #parameters['double5'] : double5==null ? '' :getText('double.format',{double5})}"
/>
<s
:
textfield
name=
"double6"
key=
"double6.prompt"
/>
<s
:
submit
key=
"Form.submitText"
method=
"execute"
/>
</s
:
form
>
<br/>
<s
:
url
id=
"url"
action=
"FormDouble"
method=
"cancel"
/>
<s
:
a
href=
"%{url}"
><s
:
text
name=
"Form.cancelText"
/></s
:
a
>
<br/>
<s
:
url
id=
"url"
action=
"FormDouble"
method=
"clearModel"
/>
<s
:
a
href=
"%{url}"
><s
:
text
name=
"Form.clearModel"
/></s
:
a
>
</body>
</html>
Les lignes 13 à 18 sont les six zones de saisie des nombres réels. Les champs double2 à double5 ont un attribut value complexe. Normalement les six champs de saisie devraient être les suivants :
2.
3.
4.
5.
6.
<s
:
textfield
name=
"double1"
key=
"double1.prompt"
/>
<s
:
textfield
name=
"double2"
key=
"double2.prompt"
/>
<s
:
textfield
name=
"double3"
key=
"double3.prompt"
/>
<s
:
textfield
name=
"double4"
key=
"double4.prompt"
/>
<s
:
textfield
name=
"double5"
key=
"double5.prompt"
/>
<s
:
textfield
name=
"double6"
key=
"double6.prompt"
/>
Pour résoudre certains problèmes rencontrés lors des tests, il a fallu complexifier les choses. Pour l'instant, le lecteur peut ignorer cette complexité. Nous l'expliquerons ultérieurement.
XIII-E. La vue de confirmation▲
La vue de confirmation [ConfirmationFormDouble.jsp] est la suivante :
Son code est le suivant :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
<%@
page
contentType
=
"text/html; charset=UTF-8"
pageEncoding=
"UTF-8"
%>
<%@
taglib
prefix
=
"s"
uri
=
"/struts-tags"
%>
<html>
<head>
<title><s
:
text
name=
"Confirmation.titre"
/></title>
<s
:
head
/>
</head>
<body background=
"<s:url value="
/ressources/standard.jpg
"/>"
>
<h2><s
:
text
name=
"Confirmation.message"
/></h2>
<table border=
"1"
>
<tr>
<th><s
:
text
name=
"Confirmation.champ"
/></th>
<th><s
:
text
name=
"Confirmation.valeur"
/></th>
</tr>
<tr>
<td><s
:
text
name=
"double1.prompt"
/></td>
<td><s
:
text
name=
"double1"
/></td>
</tr>
<tr>
<td><s
:
text
name=
"double2.prompt"
/></td>
<td>
<s
:
text
name=
"double.format"
>
<s
:
param
value=
"double2"
/>
</s
:
text
>
</td>
</tr>
<tr>
<td><s
:
text
name=
"double3.prompt"
/></td>
<td>
<s
:
text
name=
"double.format"
>
<s
:
param
value=
"double3"
/>
</s
:
text
>
</td>
</tr>
<tr>
<td><s
:
text
name=
"double4.prompt"
/></td>
<td>
<s
:
text
name=
"double.format"
>
<s
:
param
value=
"double4"
/>
</s
:
text
>
</td>
</tr>
<tr>
<td><s
:
text
name=
"double5.prompt"
/></td>
<td>
<s
:
text
name=
"double.format"
>
<s
:
param
value=
"double5"
/>
</s
:
text
>
</td>
</tr>
<tr>
<td><s
:
text
name=
"double6.prompt"
/></td>
<td><s
:
text
name=
"double6"
/></td>
</tr>
</table>
<br/>
<s
:
url
id=
"url"
action=
"FormDouble!input"
/>
<s
:
a
href=
"%{url}"
><s
:
text
name=
"Confirmation.lien"
/></s
:
a
>
</body>
</html>
La ve [ConfirmationFormDouble.jsp] se contente d'afficher le modèle [FormDoubleModel]. Les lignes 47-49 montrent l'affichage d'un nombre réel. On veut que cet affichage tienne compte de la localisation de l'application. Selon celle-ci, un nombre réel ne s'affichera pas de la même façon en France (10,7) et en Grande-Bretagne (10.7). Pour cela, on utilise la balise <s:text> qu'on avait utilisée jusque là pour l'internationalisation de l'application. Cette balise sert donc également pour la localisation.
Ici, la clé de message utilisée est double.format. Cette clé est trouvée dans le fichier [FormDoubleModel.properties] :
double.format={0,number}
La valeur associée à la clé n'est pas ici un message, mais un format d'affichage :
- 0 est un paramètre représentant la valeur à afficher. Ici ce sera le champ double5 du modèle.
- number représente le format numérique. Il sera adapté à chaque pays. Sans ce format, le nombre 10.7 sera toujours affiché 10.7 quelque soit le pays.
La balise
Fait afficher le message {0, number} où le paramètre double5 (ligne 2) viendra remplacer le paramètre 0 du format. Ainsi, le modèle double5 sera affiché au format numérique localisé.
XIII-F. Le modèle [FormDoubleModel]▲
Les champs double1 à double6 du formulaire [FormDouble.jsp] sont injectés dans le modèle [FormDoubleModel] suivant :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
package
example;
public
class
FormDoubleModel {
// constructeur sans paramètre
public
FormDoubleModel
(
) {
}
// champs
private
String double1;
private
Double double2;
private
Double double3;
private
Double double4;
private
Double double5;
private
String double6;
// raz modèle
public
void
clearModel
(
) {
double1 =
null
;
double2 =
null
;
double3 =
null
;
double4 =
null
;
double5 =
null
;
double6 =
null
;
}
// getters et setters
...
}
- les champs double1 et double6 sont de type String
- les autres champs sont de type Double
XIII-G. La validation du modèle▲
La validation du modèle est contrôlée par deux fichiers : [FormDouble-validation.xml] et [FormDoubleModel-validation.xml].
Le fichier [FormDouble-validation.xml] délègue les validations à [FormDoubleModel-validation.xml] :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
<!--
<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//
EN" "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
-->
<!DOCTYPE validators PUBLIC
"-//OpenSymphony Group//XWork Validator 1.0.2//
EN"
"http://localhost:8084/exemple-10/example/xwork-validator-1.0.2.dtd"
>
<validators>
<field
name
=
"model"
>
<field-validator
type
=
"visitor"
>
<param
name
=
"appendPrefix"
>
false</param>
<message/>
</field-validator>
</field>
</validators>
Nous avons déjà rencontré ce fichier.
Le fichier [FormDoubleModel-validation.xml] contient les règles de validation suivantes :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
<!--
<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//
EN" "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
-->
<!DOCTYPE validators PUBLIC
"-//OpenSymphony Group//XWork Validator 1.0.2//
EN"
"http://localhost:8084/exemple-10/example/xwork-validator-1.0.2.dtd"
>
<validators>
<field
name
=
"double1"
>
<field-validator
type
=
"requiredstring"
short-circuit
=
"true"
>
<message
key
=
"double1.error"
/>
</field-validator>
<field-validator
type
=
"regex"
short-circuit
=
"true"
>
<param
name
=
"expression"
>
^[+|-]*\s*\d+(,\d+)*$</param>
<param
name
=
"trim"
>
true</param>
<message
key
=
"double1.error"
/>
</field-validator>
</field>
<field
name
=
"double2"
>
<field-validator
type
=
"required"
short-circuit
=
"true"
>
<message
key
=
"double2.error"
/>
</field-validator>
<field-validator
type
=
"conversion"
short-circuit
=
"true"
>
<message
key
=
"double2.error"
/>
</field-validator>
</field>
<field
name
=
"double3"
>
<field-validator
type
=
"required"
short-circuit
=
"true"
>
<message
key
=
"double3.error"
/>
</field-validator>
<field-validator
type
=
"conversion"
short-circuit
=
"true"
>
<message
key
=
"double3.error"
/>
</field-validator>
<field-validator
type
=
"double"
short-circuit
=
"true"
>
<param
name
=
"minInclusive"
>
2.64</param>
<message
key
=
"double3.error"
/>
</field-validator>
</field>
<field
name
=
"double4"
>
<field-validator
type
=
"required"
short-circuit
=
"true"
>
<message
key
=
"double4.error"
/>
</field-validator>
<field-validator
type
=
"conversion"
short-circuit
=
"true"
>
<message
key
=
"double4.error"
/>
</field-validator>
<field-validator
type
=
"double"
short-circuit
=
"true"
>
<param
name
=
"maxExclusive"
>
8.32</param>
<message
key
=
"double4.error"
/>
</field-validator>
</field>
<field
name
=
"double5"
>
<field-validator
type
=
"required"
short-circuit
=
"true"
>
<message
key
=
"double5.error"
/>
</field-validator>
<field-validator
type
=
"conversion"
short-circuit
=
"true"
>
<message
key
=
"double5.error"
/>
</field-validator>
<field-validator
type
=
"double"
short-circuit
=
"true"
>
<param
name
=
"minInclusive"
>
2.64</param>
<param
name
=
"maxExclusive"
>
8.32</param>
<message
key
=
"double5.error"
/>
</field-validator>
</field>
<field
name
=
"double6"
>
<field-validator
type
=
"requiredstring"
short-circuit
=
"true"
>
<message
key
=
"double6.error"
/>
</field-validator>
<field-validator
type
=
"regex"
short-circuit
=
"true"
>
<param
name
=
"expression"
>
^[+|-]*\s*\d+(,\d+)*$</param>
<param
name
=
"trim"
>
true</param>
<message
key
=
"double6.error"
/>
</field-validator>
</field>
</validators>
- la règle des lignes 12-21 vérifie que le champ de saisie double1 suit le modèle d'une expression régulière représentant un nombre réel.
- la règle des lignes 23-30 vérifie que le champ de saisie double2 peut être converti en un réel double.
- la règle des lignes 32-43 vérifie que le champ de saisie double3 peut être converti en un réel double >=2.64. On notera qu'il faut utiliser la notation anglo-saxonne des réels.
- la règle des lignes 45-56 vérifie que le champ de saisie double4 peut être converti en un réel double <8.32.
- la règle des lignes 58-70 vérifie que le champ de saisie double5 peut être converti en un réel double dans l'intervalle [2.64,8.32[.
- la règle des lignes 72-80 vérifie que le champ double6 suit le modèle d'une expression régulière représentant un nombre réel.
Une fois le fichier [FormDoubleModel-validation.xml] exploité par l'intercepteur de validation, celui-ci fait exécuter la méthode validate de l'action [FormDouble] si elle existe. Nous allons la présenter en même temps que la totalité de l'action.
XIII-H. L'action [FormDouble]▲
L'action [FormDouble] est la suivante :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
package
example;
import
com.opensymphony.xwork2.ActionSupport;
import
com.opensymphony.xwork2.ModelDriven;
import
java.util.Map;
import
org.apache.struts2.interceptor.SessionAware;
import
org.apache.struts2.interceptor.validation.SkipValidation;
public
class
FormDouble extends
ActionSupport implements
ModelDriven, SessionAware {
// constructeur sans paramètre
public
FormDouble
(
) {
}
// modèle de l'action
public
Object getModel
(
) {
if
(
session.get
(
"model"
) ==
null
) {
session.put
(
"model"
, new
FormDoubleModel
(
));
}
return
session.get
(
"model"
);
}
@SkipValidation
public
String clearModel
(
) {
// raz du modèle
((
FormDoubleModel) getModel
(
)).clearModel
(
);
// résultat
return
INPUT;
}
public
String cancel
(
) {
// on nettoie le modèle
((
FormDoubleModel) getModel
(
)).clearModel
(
);
// résultat
return
"cancel"
;
}
// SessionAware
Map<
String, Object>
session;
public
void
setSession
(
Map<
String, Object>
session) {
this
.session =
session;
}
// validation
@Override
public
void
validate
(
) {
// saisie double6 valide ?
if
(
getFieldErrors
(
).get
(
"double6"
) ==
null
) {
// on remplace la virgule par le point dans la chaîne double6
String strDouble6 =
(((
FormDoubleModel) getModel
(
)).getDouble6
(
)).replace
(
','
, '.'
);
// String --> double
double
double6 =
Double.parseDouble
(
strDouble6);
// vérification
if
(
double6 <
2.64
||
double6 >
8.32
) {
addFieldError
(
"double6"
, getText
(
"double6.error"
));
}
}
}
}
L'action [FormDouble] est bâtie sur le même modèle que l'action [FormInt]. Nous ne commenterons que la méthode validate. On rappelle que la méthode validate est exécutée après exploitation du fichier de validation [FormDoubleModel-validation.xml] et avant l'exécution de la méthode execute.
- ligne 48 : s'il y a déjà des erreurs sur le champ double6, on ne fait rien de plus.
- ligne 50 : on a eu une chaîne de la forme 45,67. Elle a été stockée dans le champ double6 du modèle. On remplace la virgule par le point pour avoir 45.67.
- ligne 52 : la chaîne 45.67 est transformée en réel double. Ca doit marcher puisque la chaîne double6 respecte le format d'un nombre réel.
- ligne 54 : on vérifie que le réel double obtenu est dans l'intervalle [2.64, 8.32].
- ligne 55 : si ce n'est pas le cas, le message d'erreur de clé double6.error est attaché au champ double6. Ce message sera trouvé dans le fichier [FormDoubleModel.properties]. Il sera affiché quand le formulaire erroné sera réaffiché.
XIII-I. Derniers détails▲
Maintenant, retour à la complexité des champs de saisie du formulaire [FormDouble.jsp]. On va raisonner sur le champ double2. Le raisonnement s'étend aux champs double3 à double5 qui ont un modèle de type Double. Pour les champs double1 et double6 qui ont un modèle de type String, il n'y a pas de problème.
Le champ de saisie double2 est le suivant :
<s
:
textfield
name=
"double2"
key=
"double2.prompt"
value=
"%{#parameters['double2']!=null ? #parameters['double2'] : double2==null ? '' :getText('double.format',{double2})}"
/>
Partons de la balise la plus simple :
<s
:
textfield
name=
"double2"
key=
"double2.prompt"
/>
et regardons ce qui se passe :
- en [1], on valide le nombre double2 correct. Sur la copie d'écran, ça ne se voit pas très bien mais on tapé le nombre avec une virgule.
- en [2], la vue de confirmation. La saisie double2 a passé les tests de validation. Le nombre est affiché avec une virgule.
- en [3], on revient au formulaire
- en [4], le formulaire. Ce que montre mal la copie d'écran c'est que nombre double2 qui était initialement 4,32 est devenu 4.32 avec un point décimal.
- en [5], on revalide le formulaire sans rien changer
- en [6], une erreur est signalée sur le champ double2.
Le problème est le suivant :
- initialement dans [1], la chaîne de saisie "4,32" a été transformée avec succès en nombre réel 4.32. Ce qui veut dire que l'opération String --> Double a réussi et que donc dans ce sens Struts tient compte de la locale, ici la France.
- le nouveau formulaire [4] affiche dans le champ double2 la valeur du réel 4.32. Comme on n'a pas localisé l'affichage, il l'affiche par défaut à l'anglo-saxonne, c.a.d. avec un point décimal. Donc dans le sens Double --> String, Struts ne tient plus compte de la locale sinon il aurait affiché 4,32 avec une virgule.
C'est pour le moins incohérent. Mais qu'à cela ne tienne, on va localiser l'affichage du nombre 4.32. La balise de saisie devient la suivante :
<s
:
textfield
name=
"double2"
key=
"double2.prompt"
value=
"%{getText('double.format',{double2})}"
/>
L'attribut value précise la valeur à afficher dans le champ double2. Celle-ci est celle d'une expression OGNL. Rappelons la définition de la clé double.format dans le fichier [FormDoubleModel.properties] :
double.format={0,number}
La méthode getText('clé') permet d'avoir le message associé à une clé. Celui-ci est cherché dans le fichier correspondant à la locale courante. Ainsi si celle-ci était es (Espagne), la clé double.format aurait été cherchée dans le fichier [FormDoubleModel_es.properties].
La méthode getText('clé', {param0, param1, ...}) permet de retrouver un message paramétré. Le message
{0, number}
est un message paramétré par le paramètre 0. Celui-ci est un paramètre positionnel. La méthode getText('double.format', {double2}) va affecter le nombre double2 au paramètre 0. Au final, on demande la valeur de double2 au format numérique localisé. En France, le nombre 4.56 sera localisé en chaîne "4,56".
Après cette transformation, on refait les tests.
Dès l'affichage initial du formulaire, on a une anomalie en [1]. Revenons à la balise :
<s
:
textfield
name=
"double2"
key=
"double2.prompt"
value=
"%{getText('double.format',{double2})}"
/>
A l'affichage initial, la valeur du modèle double2 est null, une valeur non numérique. On fait évoluer la balise de la façon suivante :
<s
:
textfield
name=
"double2"
key=
"double2.prompt"
value=
"%{double2==null ? '' : getText('double.format',{double2})}"
/>
Cette fois-ci, on teste si double2==null. Si oui, on affiche une chaîne vide.
Ce changement fait, nous reprenons les tests :
Les écrans [1] à [4] montrent que le problème que l'on cherchait à résoudre est résolu :
- en [1], on saisit 4,67
- en [2], ce nombre a été accepté
- en [3], il est réaffiché comme 4,67 avec la virgule ce qui est confirmé par [4].
Malheureusement, les problèmes ne s'arrêtent pas là. Regardons la séquence suivante :
- en [5], on ajoute un caractère pour invalider double2
- en [6], les tests de validation ont fait leur travail et l'erreur est signalée. Seulement la chaîne affichée en [6] n'est pas la chaîne erronée mais l'actuelle valeur du modèle double2. On a perdu la valeur saisie.
Lorsqu'on passe de [5] à [6] la requête ne va pas jusqu'à son terme. Elle est arrêtée par l'intercepteur de validation. En [6] on a affiché la valeur du modèle double2 qui n'a pas reçu de nouvelle valeur à cause de cet arrêt. C'est donc sa précédente valeur qui est affichée alors qu'il aurait fallu afficher la chaîne saisie. Les paramètres d'une requête sont disponibles à une vue via la notation #parameters['param']. On fait évoluer le champ de saisie double2 de la façon suivante :
<s
:
textfield
name=
"double2"
key=
"double2.prompt"
value=
"%{#parameters['double2']!=null ? #parameters['double2'] : double2==null ? '' : getText('double.format',{double2})}"
/>
La valeur affichée du champ double2 est calculée comme suit : si le paramètre 'double2' existe alors on l'affiche sinon on affiche le modèle double2. Le lecteur est invité à tester que cette nouvelle mouture de la balise résoud les problèmes rencontrés.
XIII-J. Conclusion▲
Il est étonnant que saisir des nombres réels avec contrôle de validité soit aussi compliqué... Peut-être ai-je raté quelque chose dans la documentation ?