IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JSF Java Discussion :

[JSF 2] Problème: mon h:commandButton auto-soumet le formulaire dès son affichage.


Sujet :

JSF Java

  1. #1
    Membre très actif

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    608
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 608
    Par défaut [JSF 2] Problème: mon h:commandButton auto-soumet le formulaire dès son affichage.
    Bonjour,

    Mon formulaire contient cette instruction:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <h:commandButton id="btnRemiseDevoir" action="#{espace.remiseDevoir(sujet.getUV().id, sujet.id)}" value="${l7.btn_remiseDevoir}" styleClass="s0 s7 s7_remiseDevoir" />
    J'ai constaté qu'il s'auto-soumet dès l'affichage de la page web.
    C'est à dire que la méthode remiseDevoir s'exécute (et échoue en le faisant) alors que le formulaire n'est pas encore affiché, que l'utilisateur n'a encore rien saisi dedans.

    Est-ce du à la présence de paramètres dans la méthode placée dans l'attribut action? (Ce serait une mauvaise pratique?)
    Que peut-il m'arriver d'autre qui pourrait provoquer cet incident?

    En vous remerciant,

    Grunt.

  2. #2
    Rédacteur
    Avatar de romaintaz
    Homme Profil pro
    Java craftsman
    Inscrit en
    Juillet 2005
    Messages
    3 790
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Java craftsman
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2005
    Messages : 3 790
    Par défaut
    Hum non, il n'y a pas de raison. On dirait plutôt un code JavaScript qui s'exécute et qui soumet le formulaire (avec quelque chose du genre form.submit();).

    As-tu du JavaScript dans ta page (regarde son code source) ?
    Nous sommes tous semblables, alors acceptons nos différences !
    --------------------------------------------------------------
    Liens : Blog | Page DVP | Twitter
    Articles : Hudson | Sonar | Outils de builds Java Maven 3 | Play! 1 | TeamCity| CitConf 2009
    Critiques : Apache Maven

  3. #3
    Membre très actif

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    608
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 608
    Par défaut
    L'application utilise primefaces, mais je n'ai pas utilisé de fonctionnalités Javascript dedans, même implicites: je n'ai pas d'attributs update, par exemple.

    La variante employant p:commandButton
    a le même effet que le h:commandButton que j'ai présenté en exemple.

    Grunt.

  4. #4
    Rédacteur
    Avatar de romaintaz
    Homme Profil pro
    Java craftsman
    Inscrit en
    Juillet 2005
    Messages
    3 790
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Java craftsman
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2005
    Messages : 3 790
    Par défaut
    Tu peux nous montrer le code de ta page?
    Nous sommes tous semblables, alors acceptons nos différences !
    --------------------------------------------------------------
    Liens : Blog | Page DVP | Twitter
    Articles : Hudson | Sonar | Outils de builds Java Maven 3 | Play! 1 | TeamCity| CitConf 2009
    Critiques : Apache Maven

  5. #5
    Membre très actif

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    608
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 608
    Par défaut
    Voici le formulaire complet, il est dans un composite:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    <cc:implementation>
       <f:loadBundle basename="web.auditeurs.accueil.eleve.PresentationSujet" var="l7" />
     
          <h:form id="sujet" styleClass="f0 f7 f7_sujet">
    	      <!-- Affichage de la description détaillée du sujet selon son activité et sa règle. -->
    	      <c:if test="${cc.attrs.sujet.hasDescription(espace.requestLocales)}">
    	         <c:if test="${cc.attrs.sujet.isAffichableActif()}">
    	            <span class="bt0 bt7 bt7_description_sujet"><h:outputText value="${cc.attrs.sujet.getDescriptionSujetActif(espace.requestLocales)}" escape="false" /></span>
    	         </c:if>
     
    	         <c:if test="${cc.attrs.sujet.isAffichableActif() eq false and cc.attrs.sujet.isAffichableInactif() and cc.attrs.sujet.detailAffichageInactif eq 'DETAIL'}">
    	             <span class="bt0 bt7 bt7_description_sujet"><h:outputText value="${cc.attrs.sujet.getDescriptionSujetInactif(espace.requestLocales)}" escape="false" /></span>
    	         </c:if>
    	      </c:if>
     
    	      <!-- Si le sujet est un devoir, présenter son formulaire de remise. -->
    	      <c:if test="${cc.attrs.sujet.type eq 'EXAMEN'}">
    	         <c:if test="${cc.attrs.sujet.piecesReclamees.hasInformation(espace.requestLocales)}">
    	            <span class="bt0 bt7 bt7_annonceRemise"><h:outputText value="${cc.attrs.sujet.piecesReclamees.getInformation(espace.requestLocales)}" escape="false" styleClass="t0 t7 t7_annonceRemise" /></span><br/>
    	         </c:if>
     
    	         <c:set var="devoir" value="${espace.obtenirDevoir(sujet)}" />
    	         <c:set var="piecesAutrefois" value="${devoir != null ? devoir.getPiecesRenvoyees() : null}" />
     
    	         <table class="table0 table7 t7_pieces_reclamees">      
    		         <c:forEach var="piece" items="#{cc.attrs.sujet.getPiecesReclamees()}">
    		            <c:set var="autrefois" value="${piecesAutrefois != null ? piecesAutrefois.getPiece(piece.getClef()) : null}" />
     
    		            <ue:reclame devoir="${devoir}" sujet="${cc.attrs.sujet}" piece="${piece}" autrefois="${autrefois}" />
    		         </c:forEach>
    	         </table>
     
    	         <p:commandButton id="btnRemiseDevoir" action="#{espace.remiseDevoir(sujet.getUV().id, sujet.id)}" value="${l7.btn_remiseDevoir}" ajax="false" styleClass="s0 s7 s7_remiseDevoir" />
                <!-- h:commandButton id="btnRemiseDevoir" action="#{espace.remiseDevoir(sujet.getUV().id, sujet.id)}" value="${l7.btn_remiseDevoir}" styleClass="s0 s7 s7_remiseDevoir" / -->
    	      </c:if>
          </h:form>
    <cc:implementation>

    Le <ue:reclame> auquel fait référence ce formulaire contient ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
       <cc:implementation>
          <f:loadBundle basename="web.auditeurs.accueil.eleve.Reclame" var="l8" />
     
          <c:if test="${cc.attrs.piece.requis eq 'OBLIGATOIRE' or cc.attrs.piece.requis eq 'FACULTATIVE'}">
             <!-- Pièce ${cc.attrs.piece.requis.name()} "${cc.attrs.piece.getDescription(espace.requestLocales)}" de clef: "${cc.attrs.piece.clef}". -->
             <tr class="ligne0 ligne8 l8_piece_reclamee">
                <td class="bt0 bt8 bt8_descriptionPiece"><h:outputText value="${cc.attrs.piece.getDescription(espace.requestLocales)}" styleClass="t0 t8 t8_descriptionPiece" /></td>
                <c:if test="${piece.type.name() eq 'TEXTE'}">       
                   <!-- Si la pièce possède un nom associé, un fichier ayant ce contenu sera recherché:
                        - D'abord dans les éléments déjà remis par cet élève.
                        - Ensuite dans une annexe du sujet. -->
                   <td class="bt0 bt8 bt8_precedenteRemiseTexte">
                      <h:inputTextarea id="texte${piece.clef}" styleClass="t0 t8 ${piece.requis.name() eq 'OBLIGATOIRE' ? 't8_precedenteRemiseTexteObligatoire' : 't8_precedenteRemiseTexteFacultative'}" cols="${l8.zoneSaisie_colsTextArea}" rows="${l8.zoneSaisie_rowsTextArea}" value="${espace.textes.getRemise(sujet.getUV().id, sujet.id, piece.clef).contenu}" />
                   </td>
                </c:if>
     
                <c:if test="${piece.type.name() ne 'TEXTE'}">
                   <td class="bt0 bt8 bt8_precedenteRemiseFichier">
                      <hh:inputFile id="fichier${piece.clef}" value="#{uploadBean.getUpload(piece.clef).file}" styleClass="t0 t8 ${piece.requis.name() eq 'OBLIGATOIRE' ? 't8_precedenteRemiseFichierObligatoire' : 't8_precedenteRemiseFichierFacultative'}" directory="c:/temp/essai" />
                   </td>
                </c:if>
             </tr>
          </c:if>
       </cc:implementation>

    Et le formulaire incriminé est concrètement est appelé par cette page:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
             <p:tabView>
                <c:forEach var="inscription" items="#{us.auditeur.inscriptions}">
                   <c:set var="ue" value="${us.getUV(inscription.getUVId())}" />
     
                   <p:tab title="#{espace.getLibelleUE(ue)}" styleClass="b0 b6 b6_tab_ue">
                      <p:accordionPanel autoHeight="false" styleClass="b0 b6 b6_accordeon_sujets">
                         <!-- Présenter tous les sujets auxquels cet élève est autorisé, et qui sont affichables à la date du jour. -->
                         <c:forEach var="sujet" items="#{ue.sujets}">
    				            <c:if test="${sujet.isAuditeurAutorise(us.auditeur) and espace.isSujetAffichable(sujet)}">
    				               <!-- TODO Reste à afficher: note, nombre de remises autorisées. -->
    				               <p:tab title="${espace.getLibelleSujet(sujet, espace.requestLocales)}" styleClass="b0 b6 b6_tab_sujet">
                                  <ue:presentationSujet sujet="${sujet}" />
    				               </p:tab>
    				            </c:if>
                         </c:forEach>
                      </p:accordionPanel>
                   </p:tab>
                </c:forEach>
             </p:tabView>
    Remarque: Cette page utilise un layout, mais je n'en donne pas le détail.
    Je ne pense pas qu'il soit utile pour l'étude.


    Le symptôme, c'est qu'avant que le formulaire ne soit affiché, il s'est déjà auto-soumis. Ou en tout cas, JSF a voulu évaluer déjà le contenu de l'attribut action associé au commandButton, alors qu'il est trop tôt:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    java.lang.AssertionError: Lors de l'upload, aucun fichier n'est associé à la clef 0
    	at web.auditeurs.accueil.eleve.AccueilBean.contrôlerExtensionsFichiers(AccueilBean.java:275)
    	at web.auditeurs.accueil.eleve.AccueilBean.remiseDevoir(AccueilBean.java:218)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    	at java.lang.reflect.Method.invoke(Method.java:597)
    	at javax.el.BeanELResolver.invokeMethod(BeanELResolver.java:737)
    	at javax.el.BeanELResolver.invoke(BeanELResolver.java:467)
    	at javax.el.CompositeELResolver.invoke(CompositeELResolver.java:246)
    	at com.sun.el.parser.AstValue.getValue(AstValue.java:111)
    	at com.sun.el.parser.AstValue.getValue(AstValue.java:163)
    	at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:219)
    	at com.sun.faces.facelets.el.ELText$ELTextVariable.toString(ELText.java:214)
    	at com.sun.faces.facelets.el.ELText$ELTextComposite.toString(ELText.java:155)
    	at com.sun.faces.facelets.compiler.CommentInstruction.write(CommentInstruction.java:77)
    	at com.sun.faces.facelets.compiler.UIInstructions.encodeBegin(UIInstructions.java:82)
    	at com.sun.faces.facelets.compiler.UILeaf.encodeAll(UILeaf.java:183)
    	at javax.faces.render.Renderer.encodeChildren(Renderer.java:168)
    	at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:853)
    	at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:304)
    	at com.sun.faces.renderkit.html_basic.GroupRenderer.encodeChildren(GroupRenderer.java:105)

    En pièce jointe, le code source HTML produit lorsque je mets les instructions de ma fonction remiseDevoir en commentaire pour que le formulaire puisse s'afficher. Il mériterait un coup d'équarrissage W3C XHTML (15 incidents), mais je ne vois rien qui provoque un auto-submit dedans.
    Je vais toutefois me concentrer sur la résolution de ces problèmes de compliance XHTML, on ne sait jamais, ce serait trop bête...

    En autre pièce jointe, une image écran de ce que le site présente lorsqu'il fonctionne: chaque tabulation de l'accordéon présente un formulaire.

    Grunt.

  6. #6
    Membre très actif

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    608
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 608
    Par défaut
    Je suis pas parvenu à obtenir le fin mot de l'histoire.

    Pour me sortir d'affaire, j'ai modifié mon code ainsi:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    <p:commandButton id="btnRemiseDevoir" action="#{espace.remiseDevoir}" value="${l7.btn_remiseDevoir}" ajax="false" styleClass="s0 s7 s7_remiseDevoir">
     	<f:setPropertyActionListener target="#{espace.devoirRemisUE}" value="${sujet.getUV().id}" />
     	<f:setPropertyActionListener target="#{espace.devoirRemisSujet}" value="${sujet.id}" />
    </p:commandButton>
    Plus d'auto-soumission intempestive, mais cela ne me donne pas d'explication pour autant. Etait-ce le fait que l'action soit une méthode à paramètres qui posait problèmes?

    Grunt.

Discussions similaires

  1. Réponses: 1
    Dernier message: 27/11/2009, 15h32
  2. Réponses: 2
    Dernier message: 10/08/2007, 23h49
  3. Problème: mon lecteur a le hoquet
    Par t26 dans le forum Périphériques
    Réponses: 6
    Dernier message: 30/06/2006, 15h13
  4. Problèmes sur clé primaire : auto index
    Par ultracoxy dans le forum Requêtes
    Réponses: 12
    Dernier message: 20/06/2006, 17h43
  5. Réponses: 3
    Dernier message: 09/12/2005, 03h04

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo