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>
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.
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.)
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
<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();
}
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
Essayez d’utiliser p: ajax avec l’attribut event,
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
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.