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 :

Lancer une action sur le changement d'état d'une case à cocher


Sujet :

JSF Java

  1. #1
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 801
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 801
    Points : 34 063
    Points
    34 063
    Billets dans le blog
    14
    Par défaut Lancer une action sur le changement d'état d'une case à cocher
    Bonjour,

    J'affiche une liste de stages dans un tableau dont chaque ligne comporte une case à cocher pour sélectionner le stage.
    J'aimerais lancer une action de vérification lorsque l'utilisateur coche une case. J'ai essayé d'utiliser la propriété onChange proposée par JBossTools sur le contrôle mais j'obtiens une belle erreur.

    Mon contrôle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    <h:selectBooleanCheckbox id="choisir" 
                                   value="#{listeStages.selection[dataItem.ssnId]}" 
                                   onchange="#{listeStages.verifNbChoix}"/>
    L'erreur :
    javax.faces.FacesException: javax.el.PropertyNotFoundException: /listeStages.xhtml @31,60 onchange="#{listeStages.verifNbChoix}": Property 'verifNbChoix' not found on type org.domain.stamas.session.ListeStages_$$_javassist_seam_4
    J'ai aussi essayé avec onchange="#{listeStages.verifNbChoix()}" mais sans succès.

    Je vois dans la FAQ que cette propriété ne semble pas faire partie de ce contrôle.

    Comment puis-je faire ?

  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
    Points : 7 275
    Points
    7 275
    Par défaut
    L'attribute onchange exécute une fonction Javascript (donc côté client) à la modification de la valeur.

    Si tu souhaites exécuter une action côté serveur, donc en Java, il te faudra passer par de l'Ajax. Un exemple avec Richfaces :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    <h:selectBooleanCheckbox id="choisir" value="#{listeStages.selection[dataItem.ssnId]}">
        ...
        <a4j:support event="onchange" actionListener="#{listeStages.verifNbChoix}"/>
    </h:selectBooleanCheckbox>
    Ton bean listeStages devant alors proposer la méthode suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public void verifNbChoix(ActionEvent evt) { ... }

  3. #3
    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
    Points : 7 275
    Points
    7 275
    Par défaut
    Citation Envoyé par CinePhil Voir le message
    Je vois dans la FAQ que cette propriété ne semble pas faire partie de ce contrôle.
    Au fait, la FAQ n'est pas (et ne se veut pas) exhaustive sur ce point.

    Je te conseille de regarder la Javadoc-TLD des balises de base de JSF (pour la version 1.2), ici :

    http://download.oracle.com/javaee/5/...ocs/index.html

  4. #4
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 801
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 801
    Points : 34 063
    Points
    34 063
    Billets dans le blog
    14
    Par défaut
    Je n'ai pas d'erreur mais ou bien il manque un truc, ou bien c'est ma fonction qui ne fonctionne pas !

    Le but est de vérifier que l'utilisateur ne coche pas plusieurs lignes.
    C'est vrai que pour cette appli, j'aurais pu utiliser des boutons radio à la place des cases à cocher mais on veut rendre générique cette partie d'inscription à un stage qui pourrait, dans une autre appli, être une inscription à autre chose avec plusieurs choix possibles.

    Les deux fonctions utilisées :
    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
        /**
         * Récupère les identifiants des lignes sélectionnées
         * @return Integer : Le nombre de sélections dans le tableau
         */
        public Integer lignesSelectionnees()
        {
            dataList = new ArrayList<ThStageStg>();
     
            for (ThStageStg dataItem : this.getResultList()) 
            {
                // Récupère la sélection
                if (selection.get(dataItem.getSsnId()).booleanValue())
                {
                    dataList.add(dataItem);
                    selection.remove(dataItem.getSsnId());
                }
            }
            return dataList.size();
        }
     
        /**
         * verifNbChoix
         * Vérifie que le nombre de sélections maxi dans la liste n'est pas atteint et agit en conséquence
         */
        public String verifNbChoix(ActionEvent evt)
        {
            // Récupère la sélection
            if (lignesSelectionnees() > 1) // TODO 1 à remplacer par paramètre application
            {
                facesMessages.add("Vous ne pouvez sélectionner plus d'un stage !");
                return "KO";
            }
            return "OK";
     
        }
    La case à cocher :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
                               <h:selectBooleanCheckbox id="choisir" 
                                   value="#{listeStages.selection[dataItem.ssnId]}">
                                   <a:support event="onchange" 
                                       actionListener="#{listeStages.verifNbChoix}"/>
                               </h:selectBooleanCheckbox>
    La navigation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
        <navigation from-action="#{listeStages.verifNbChoix}">
            <rule if-outcome="KO">
                <redirect/>
            </rule>
        </navigation>
    Quand je coche une deuxième case, il ne renvoie pas le faceMessage.

  5. #5
    Membre régulier
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mars 2010
    Messages
    42
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Mars 2010
    Messages : 42
    Points : 111
    Points
    111
    Par défaut
    Ne penses tu pas induire en erreur ou dérouter tes utilisateurs avec une liste qui comporte des cases à cocher et qui se comporte comme des boutons radio ?
    C'est comme si tu avais un champ de saisie dans lequel tu t'attends à mettre du texte et que le programme te laisse faire pour te dire ensuite que c'est pas permis ?

    Pour tes cases à cocher, si tu veux faire un composant générique, tu pourrais faire les deux types de liste que j'insérerai par un ui:include selon le cas. C'est une solution, il y en a sûrement d'autre plus élégantes.

  6. #6
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 801
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 801
    Points : 34 063
    Points
    34 063
    Billets dans le blog
    14
    Par défaut
    Citation Envoyé par StefGac Voir le message
    Ne penses tu pas induire en erreur ou dérouter tes utilisateurs avec une liste qui comporte des cases à cocher et qui se comporte comme des boutons radio ?
    Oui je suis assez d'accord. C'est mon chef qui insiste pour la généricité de l'inscription.
    Pour tes cases à cocher, si tu veux faire un composant générique, tu pourrais faire les deux types de liste que j'insérerai par un ui:include selon le cas. C'est une solution, il y en a sûrement d'autre plus élégantes.
    Pas bête ! Je vais y réfléchir !

    Merci pour ton aide.

  7. #7
    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
    Points : 7 275
    Points
    7 275
    Par défaut
    Tout d'abord, je suis tout à fait d'accord avec StefGac. Une checkbox signifie un choix multiple, un radio bouton signifie un choix unique. Détourner ces composants de ces conventions va dérouter l'utilisateur.

    Maintenant, concernant ton code, plusieurs remarques :

    #1 La signature de ta méthode

    Quand on utilise l'attribut action dans le XHTML, on fait référence à une méthode retournant un String et n'ayant pas de paramètre. Quelque chose du genre public String doSomething() { ... }. Cette méthode retourne une chaine de caractères correspondant à la règle de navigation à utiliser pour rediriger l'utilisateur vers la bonne page. C'est donc la façon de faire à privilégier quand on souhaite faire de la navigation.

    Quand on utilise un actionListener dans le XHTML, on fait référence à une méthode ne retournant rien, et qui prend un ActionEvent comme paramètre, comme par exemple public void doSomething(ActionEvent evt) { ... }. Bien que ce ne soit pas impossible, cette méthode est plutôt à privilégier quand on ne veut pas faire de navigation, autrement dit réaliser une action tout en restant dans la vue actuelle.

    Dans ton code, tu mélanges les deux. Ta méthode verifNbChoix ne devrait pas retourner de String (cf. point #2). Je pense que tout simplement JSF ne s'attend pas à recevoir un String, et donc ne va pas chercher à exécuter une quelconque règle de navigation.

    #2 Pas de navigation

    Considérant ton cas précis, il n'est pas du tout utile de gérer la navigation. En effet, quand verifNbChoix est appelée, tu as 2 cas possibles :

    1. L'utilisateur a 0 ou 1 case cochée. Il ne faut donc rien faire.
    2. L'utilisateur vient de cocher sa 2e case. Dans ce cas, il faut ajouter un FacesMessage, puis l'afficher sur la même page. Donc pas de besoin de navigation.

    En gros, voilà ce que donnerait ton code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    public void verifNbChoix(ActionEvent evt) {
        if (lignesSelectionnees() > 1) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Vous ne pouvez pas sélectionner plusieurs stages."));
        }
    }
    Ton cas de navigation est à supprimer.

    Enfin, dans le code XHTML, nous avons besoin d'afficher ces messages d'erreur. 2 options :

    1. Tu rafraichit spécifiquement un panel contenant (éventuellement) les messages d'erreur, grâce à l'attribut reRender :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    <a4j:outputPanel id="messagesBox">
        <h:messages/>
    </a4j:outputPanel>
    <h:selectBooleanCheckbox id="choisir" value="#{listeStages.selection[dataItem.ssnId]}">
        <a:support event="onchange" actionListener="#{listeStages.verifNbChoix}" reRender="messagesBox"/>
    </h:selectBooleanCheckbox>
    2. Tu forces le rafraichissement automatique du outputPanel, et il est donc inutile de le spécifier dans un reRender. A noter que cela signifie qu'à chaque appel ajax sur cette page, ce bloc sera rafraichit.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    <a4j:outputPanel ajaxRendered="true">
        <h:messages/>
    </a4j:outputPanel>
    <h:selectBooleanCheckbox id="choisir" value="#{listeStages.selection[dataItem.ssnId]}">
        <a:support event="onchange" actionListener="#{listeStages.verifNbChoix}"/>
    </h:selectBooleanCheckbox>
    Voilà, j'espère que c'est plus clair maintenant.

    Autre chose : si tu continues à utiliser des checkboxes qui se comportent comme des radio boutons, tu peux aussi faire un appel en Javascript qui va vérifier le nombre de cases cochées, et éventuellement griser celles qui ne sont pas cochées (ainsi, l'utilisateur ne pourra plus en cocher une 2e).
    Ainsi, tu évites un appel serveur pour ça.
    Avec jQuery (la librairie est incluse dans Richfaces) ce n'est pas très compliqué.

Discussions similaires

  1. Lancer une action sur un port différent
    Par Mathieu Salles dans le forum Struts 1
    Réponses: 1
    Dernier message: 23/07/2013, 14h29
  2. Lancer une procédure sur un changement de liste
    Par Many31 dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 29/01/2008, 19h42
  3. Réponses: 20
    Dernier message: 12/06/2007, 10h11
  4. comment lancer automatiquement 1 script au lieu d'une action sur un boutton
    Par winnie82 dans le forum Général JavaScript
    Réponses: 16
    Dernier message: 13/07/2006, 17h13
  5. Faire a un script executer une action sur un signal
    Par vodevil dans le forum Langage
    Réponses: 1
    Dernier message: 13/12/2005, 11h14

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