web-dev-qa-db-fra.com

Primefaces valueChangeListener ou <p: l'écouteur ajax ne se déclenche pas pour p: selectOneMenu

J'utilise Primefaces 3.4.2.

J'ai les éléments suivants dans ma page JSF

<p:selectOneMenu id="emp" value="#{mymb.emp.employeeName}" 
        valueChangeListener="#{mymb.handleChange}" 
        required="true"
        style="width: 150px;">
    <f:selectItem noSelectionOption="true" 
            itemLabel="Please  Select"/>
    <f:selectItems value="#{mymb.employeeList}" var="emp"
            itemLabel="#{emp.employeeName}"
            itemValue="#{emp.employeeNumber}"/>
    <p:ajax update="sublist"/>
</p:selectOneMenu>

et dans ManagedBean

public void handleChange(ValueChangeEvent event){  
    System.out.println("here "+event.getNewValue());
}

Le problème est que valueChangeListener ne se déclenche pas, c.-à-d. Que la méthode handleChange ne soit pas invoquée. J'ai essayé avec ce qui suit, mais ça ne marche pas non plus.

<p:ajax update="sublist"  listener="#{mymb.handleChange}" />  

Page distincte JSF:

<ui:composition template="/templates/layout.xhtml"
    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"
    xmlns:p="http://primefaces.org/ui">
    <ui:define name="content">
        <h:head>
        </h:head>
        <h:body>
            <h:form id="form">                      
                <p:panelGrid columns="6">
                    <h:outputLabel value="Employees" for="employees" />
                    <p:selectOneMenu id="employees"
                            value="#{mymb.employeesList}" 
                            required="true">
                        <f:selectItems value="#{mymb.employeesList}" var="emp"
                                itemLabel="#{emp.employeeName}" />
                        <p:ajax listener="#{mymb.handleChange}"   />  
                    </p:selectOneMenu>                  
                </p:panelGrid>
            </h:form>
        </h:body>
    </ui:define>
</ui:composition>
18
Jåcob

Si vous souhaitez utiliser valueChangeListener, vous devez soumettre le formulaire chaque fois qu'une nouvelle option est choisie. Quelque chose comme ça:

<p:selectOneMenu value="#{mymb.employee}" onchange="submit()"
                 valueChangeListener="#{mymb.handleChange}" >
    <f:selectItems value="#{mymb.employeesList}" var="emp"
                   itemLabel="#{emp.employeeName}" itemValue="#{emp.employeeID}" />
</p:selectOneMenu>

public void handleChange(ValueChangeEvent event){  
    System.out.println("New value: " + event.getNewValue());
}

Sinon, si vous voulez utiliser <p:ajax>, cela devrait ressembler à ceci:

<p:selectOneMenu value="#{mymb.employee}" >
    <p:ajax listener="#{mymb.handleChange}" />
    <f:selectItems value="#{mymb.employeesList}" var="emp"
                   itemLabel="#{emp.employeeName}" itemValue="#{emp.employeeID}" />
</p:selectOneMenu>

private String employeeID;

public void handleChange(){  
    System.out.println("New value: " + employee);
}

Une chose à noter est que dans votre exemple de code, j'ai vu que l'attribut value de votre <p:selectOneMenu> est #{mymb.employeesList}, ce qui est identique à la value de <f:selectItems>. La value de votre <p:selectOneMenu> devrait être semblable à mes exemples ci-dessus, qui concernent un seul employé, et non une liste d'employés.

46
Mr.J4mes

La valueChangeListener n'est nécessaire que si vous êtes intéressé à la fois par l'ancien et la nouvelle valeur.

Si vous ne vous intéressez qu'à la nouvelle valeur, l'utilisation de <p:ajax> ou <f:ajax> est le meilleur choix.

Il y a plusieurs raisons possibles pour lesquelles l'appel ajax ne fonctionne pas. Commencez par modifier la signature de la méthode handler: supprimez le paramètre. Ensuite, vous pouvez accéder directement à votre variable de bean géré:

public void handleChange(){  
  System.out.println("here "+ getEmp().getEmployeeName());
}

Au moment où l’auditeur est appelé, la nouvelle valeur est déjà définie. (Notez que je suppose implicitement que l'expression el mymb.emp.employeeName est correctement prise en charge par les méthodes getter/setter correspondantes.)

16
Matt Handy

Une autre solution consiste à mélanger valueChangeListener, ajax et processus:

<p:selectManyCheckbox id="employees" value="#{employees}" columns="1" layout="grid" valueChangeListener="#{mybean.fireSelection}"   >
    <f:selectItems var="employee" value="#{employeesSI}" />
    <p:ajax event="valueChange" immediate="true" process="@this"/>
</p:selectManyCheckbox>

La méthode dans mybean est juste:

public void fireSelection(ValueChangeEvent event) {
    log.debug("New: "+event.getNewValue()+", Old: "+event.getOldValue());
}

Comme cela, valueChangeEvent est très léger!

PS: fonctionne bien avec PrimeFaces 5.0

10
Emmanuel
<p:ajax listener="#{my.handleChange}" update="id of component that need to be rerender after change" process="@this" />



import javax.faces.component.UIOutput;
import javax.faces.event.AjaxBehaviorEvent;

public void handleChange(AjaxBehaviorEvent vce){  
  String name= (String) ((UIOutput) vce.getSource()).getValue();
}
10
codeFu

Tous peuvent être définis comme dans f:ajax attiributes.

c'est à dire.

    <p:selectOneMenu id="employees" value="#{mymb.employeesList}" required="true">
         <f:selectItems value="#{mymb.employeesList}" var="emp" itemLabel="#{emp.employeeName}" />
         <f:ajax event="valueChange" listener="#{mymb.handleChange}" execute="@this" render="@all" />
    </p:selectOneMenu>

event: il peut s'agir d'événements DOM normaux tels que click ou valueChange

execute: Ceci est une liste séparée par des espaces d'identifiants client des composants qui participeront à la partie "execute" du cycle de vie du traitement de la demande.

render: Les clientsIds des composants qui participeront à la partie "rendu" du cycle de vie du traitement de la demande. Une fois l'opération terminée, vous pouvez définir quels composants doivent être actualisés. Id, IdList ou ces mots clés peuvent être ajoutés: @this, @form, @all, @none.

Vous pouvez accéder à la liste complète des attributs en suivant le lien: http://docs.Oracle.com/javaee/6/javaserverfaces/2.1/docs/vdldocs/facelets/f/ajax.html

4
efirat

Essayez d’utiliser p: ajax avec l’attribut event,

2
Sandeep Goud

Mon problème était que nous utilisions spring securyty et que la page précédente n'appelait pas la page avec faces-redirect = true, puis la page affichait un avertissement Java et le contrôle ne déclenche pas l'événement change. 

Solution: La page précédente doit appeler la page en utilisant, faces-redirect = true

2
Edgar Diaz

cela fonctionne pour moi:

Il peut être utilisé dans la boîte de dialogue, mais celle-ci ne peut être insérée dans aucun composant tel que panneaux, accordéon, etc.

0
Geo