web-dev-qa-db-fra.com

La méthode d'écoute f: ajax dans h: selectOneMenu n'est pas exécutée

La page est générée correctement avec les valeurs appropriées dans le bean géré, mais les événements ajax dans ces deux h: selectOneMenus ne fonctionnent pas. L'auditeur n'est pas appelé. Une erreur doit être quelque part dans les balises, mais je ne la vois pas.

<f:view>
    <h:form>
        <h:messages />
        <h:panelGrid columns="3">

            <h:outputLabel value="Choose your faculty: *" for="faculties" />
            <h:selectOneMenu id="faculties" value="#{registrateStudent.selectedFaculty}" >
                <f:ajax event="change" listener="#{registrateStudent.genSpecializations}" execute="faculties" render="specializations" />                        
                <f:selectItems value="#{registrateStudent.listFaculty}" var="curFac" itemLabel="#{curFac.name}" itemValue="#{curFac}" />
            </h:selectOneMenu>
            <h:message id="message_faculties" for="faculties" />

            <h:outputLabel value="Choose your specialization: *" for="specializations" />
            <h:selectOneMenu id="specializations" value="#{registrateStudent.selectedSpecialization}" >
                <f:selectItems value="#{registrateStudent.listSpecialization}" var="curSpec" itemLabel="#{curSpec.name}" itemValue="#{curSpec}"/>
            </h:selectOneMenu>
            <h:message id="message_specializations" for="specializations" />                    

Bean géré:

@ManagedBean(name = "registrateStudent")
@ViewScoped
public class RegistrateStudent {


    private Faculty selectedFaculty;
    private List<Faculty> listFaculty;
    private Specialization selectedSpecialization;
    private List<Specialization> listSpecialization;
    private boolean showSpecialization = false;


    /** Creates a new instance of RegistrateStudent */
    public RegistrateStudent() {
        users = new Users();
        System.out.println("poaposd1");
        student = new Student();
    }

    @PostConstruct
    public void init() {
        listFaculty = ff.findAll();
        if (listFaculty != null) {
            selectedFaculty = listFaculty.get(0);
            listSpecialization = sf.findByFaculty(selectedFaculty.getIdFaculty());
            if (listSpecialization != null) {
                selectedSpecialization = listSpecialization.get(0);
            }
            else {}
        } else {}
    }

   public void genSpecializations(AjaxBehaviorEvent event) {
        if (sf.findByFaculty(selectedFaculty.getIdFaculty()) != null) {
            this.showSpecialization = true;
        } else {
            JsfUtil.addSuccessMessage("faculties", "We don't have specializations for such faculty");
        }
    }
}

MISE À JOUR:

J'ai découvert quelques choses intéressantes:

<f:ajax> la balise ne fonctionne pas sur <h:link>, <h:selectOneMenu>, <h:button>, <h:commandButton>. Dans ce cas, des valeurs incorrectes dans l'attribut render ne sont pas détectées, mais une valeur incorrecte de l'attribut event génère une erreur.

<h:outputLabel>, <h:inputText> travailler avec <f:ajax> correctement

12
kolobok

Le <f:ajax> a besoin jsf.js fichier inclus dans le HTML <head>. Il contient toutes les fonctions JS pour faire la magie ajax JSF.

Pour ce faire, assurez-vous que vous utilisez <h:head> au lieu de <head> dans le modèle principal. JSF inclura alors automatiquement les <script> élément qui pointe vers jsf.js.

<!DOCTYPE html>
<html lang="en"
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://Java.Sun.com/jsf/core"
    xmlns:h="http://Java.Sun.com/jsf/html"
    xmlns:ui="http://Java.Sun.com/jsf/facelets">
    <h:head>
        <title>Look, with h:head</title>
    </h:head>
    <h:body>
        Put your content here.
    </h:body>
</html>

Notez que dans un navigateur Web un peu décent avec un ensemble d'outils de développeur Web un peu décent comme Firefox Web Developer Toolbar et/ou Firebug vous devriez immédiatement avoir remarqué des erreurs JS comme jsf is undefined lorsque la requête ajax doit être exécutée. Cela aurait dû au moins donner matière à réflexion.


Mise à jour : selon votre mise à jour

J'ai découvert quelques choses intéressantes:

<f:ajax> la balise ne fonctionne pas sur <h:link>, <h:selectOneMenu>, <h:button>, <h:commandButton>. Dans ce cas, des valeurs incorrectes dans l'attribut render ne sont pas détectées, mais une valeur incorrecte de l'attribut event génère une erreur.

<h:outputLabel>, <h:inputText> travailler avec <f:ajax> correctement.

Le <h:link> et <h:button> sont destinés aux requêtes GET uniquement, pas aux POST requêtes. Cela devrait cependant fonctionner correctement sur <h:selectOneMenu> et <h:commandButton>. N'avez-vous pas plus de code dans l'image complète que vous avez omis de la question pour plus de simplicité? Quelle implication/version JSF utilisez-vous? Utilisez-vous les bonnes bibliothèques dans classpath? On dirait que tu dois vraiment avoir gâché quelque chose.

Pour vous convaincre (et moi-même) je viens de créer le testcase copy'n'paste'n'runnable suivant

<!DOCTYPE html>
<html lang="en"
    xmlns:h="http://Java.Sun.com/jsf/html" 
    xmlns:f="http://Java.Sun.com/jsf/core"
    xmlns:ui="http://Java.Sun.com/jsf/facelets"
>
    <h:head>
        <title>SO question 6089924</title>
    </h:head>
    <h:body>
        <h:form>
            <h:selectOneMenu value="#{bean.selected}">
                <f:selectItem itemValue="#{null}" itemLabel="Select..." />
                <f:selectItem itemValue="one" />
                <f:selectItem itemValue="two" />
                <f:selectItem itemValue="three" />
                <f:ajax listener="#{bean.listener}" render="result" />
            </h:selectOneMenu>

            <h:commandButton value="commandButton" action="#{bean.submit}">
                <f:ajax listener="#{bean.listener}" render="result" />
            </h:commandButton>

            <h:outputText id="result" value="#{bean.selected} #{bean.result}" />

            <h:messages />
        </h:form>
    </h:body>
</html>

avec ce haricot

package com.example;

import Java.io.Serializable;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.event.AjaxBehaviorEvent;

@ManagedBean
@ViewScoped
public class Bean implements Serializable {

    private String selected;
    private String result;

    public void submit() {
        System.out.println("submit");
    }

    public void listener(AjaxBehaviorEvent event) {
        System.out.println("listener");
        result = "called by " + event.getComponent().getClass().getName();
    }

    public String getSelected() {
        return selected;
    }

    public void setSelected(String selected) {
        this.selected = selected;
    }

    public String getResult() {
        return result;
    }

}

Il fonctionne correctement avec Mojarra 2.1.1 sur Tomcat 7.0.12.

INFO: Starting Servlet Engine: Apache Tomcat/7.0.12
INFO: Initializing Mojarra 2.1.1 (FCS 20110408) for context '/playground'
35
BalusC

Soyez prudent si vous avez f:metadata et f:viewparam tags puisque les setters des paramètres seront appelés à chaque requête ajax.

Pouvez-vous fournir le journal des erreurs s'il y a une erreur/exception qui est générée lorsque vous appelez l'appel ajax?

0
aseychell