Introduction à STRUTS2 par l'exemple


précédentsommairesuivant

XIII. Exemple 10 - Conversion et validation des nombres réels

La nouvelle application présente la saisie des nombres réels :

Image non disponible
  • 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 :

Image non disponible

  • 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 :

 
Sélectionnez
1.
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 :

 
Sélectionnez
1.
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 :

 
Sélectionnez
1.
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 :

 
Sélectionnez
1.
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 :

 
Sélectionnez
1.
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 :

Image non disponible

Son code est le suivant :

 
Sélectionnez
1.
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] :

 
Sélectionnez
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

 
Sélectionnez
1.
2.
3.
         <s:text name="double.format">
            <s:param value="double5"/>
</s:text>

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 :

 
Sélectionnez
1.
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] :

 
Sélectionnez
1.
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 :

 
Sélectionnez
1.
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 :

 
Sélectionnez
1.
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électionnez
<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électionnez
<s:textfield name="double2" key="double2.prompt"/>

et regardons ce qui se passe :

Image non disponible

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

Image non disponible

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

Image non disponible

  • 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électionnez
<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] :

 
Sélectionnez
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

 
Sélectionnez
{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.

Image non disponible

Dès l'affichage initial du formulaire, on a une anomalie en [1]. Revenons à la balise :

 
Sélectionnez
<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électionnez
<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 :

Image non disponible


Image non disponible

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 :

Image non disponible

  • 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électionnez
      <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 ?


précédentsommairesuivant

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2012 Serge Tahe. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.