Thibault Vandamme Thibault Vandamme - 18 days ago 10
Ajax Question

OneMenu & 2 ajax inside won't work

I'm facing a huge problem since 2 weeks.

I tested 2 ajax method one by one and they work. But when I want to have both in a oneMenu, the dropdown supposed to update the third oneMenu of the page does'nt work.

<h:body>
<h:form>

<p:growl id="growl" showDetail="true" />
<p:outputLabel value="Sélectionner une section " for="sectionBox"/>
<p:selectOneMenu id="sectionBox"
value="#{evaluationViewController.currentSection}"
converter="sectionConverter"
var="c"
filter="true"
filterMatchMode="startsWith"
effect="fade"
>
<p:ajax listener="#{evaluationViewController.onSectionSelected}" update="ue,ueO,growl"/>
<f:selectItem itemLabel="Sélectionnez uen section" itemValue="" noSelectionOption="true"/>
<f:selectItems value="#{evaluationViewController.currentSections}"
var="currentSection"
itemLabel="#{currentSection.name}"
itemValue="#{currentSection}"
/>
<p:column>
<h:outputText value="#{c.name}"/>
</p:column>
</p:selectOneMenu>

<p:outputLabel value="Sélectionner une UE " for="ue"/>
<p:selectOneMenu id="ue"
value="#{evaluationViewController.ue}"
converter="ueConverter"
var="u"
filter="true"
filterMatchMode="startsWith"
>
<p:ajax listener="#{evaluationViewController.onUeSelected}" update="ueO,growl"/>
<p:ajax event="change" update="capacities" listener="#{evaluationViewController.listenerCapacitiesUpdate}"/>
<f:selectItem itemLabel="Sélectionnez une UE" itemValue="" noSelectionOption="true"/>
<f:selectItems value="#{evaluationViewController.ues}"
var="ues"
itemLabel="#{ues.name}"
itemValue="#{ues}"
/>

<p:column>
<h:outputText value="#{u.name}"/>
</p:column>
</p:selectOneMenu>

<p:outputLabel value="Sélectionner l'UE enseignée" for="ueO"/>
<p:selectOneMenu id="ueO"
value="#{evaluationViewController.organizedUe}"
converter="organizedUeConverter"
var="o"
filter="true"
filterMatchMode="startsWith"
>
<f:selectItem itemLabel="Sélectionnez une année" itemValue="" noSelectionOption="true"/>
<f:selectItems
value="#{evaluationViewController.organizedUes}"
var="organizedUes"
itemLabel="#{organizedUes.name}"
itemValue="#{organizedUes}"
/>
<p:column>
<h:outputText value="#{o.name}"/>
</p:column>

<p:column>
<h:outputText value="#{o.level.name}"/>
</p:column>
</p:selectOneMenu>

<p:separator/>
<p:separator/>

<p:dataTable id="capacities"
var="cap"
value="#{evaluationViewController.capacities}"
editable="true"
editMode="cell"
widgetVar="cellCap"
>

<f:facet name ="header">
Capacitées
</f:facet>

<p:ajax event="cellEdit"
listener="#{evaluationViewController.onCellEdit}"
update="@this"/>

<p:column headerText="Dénomination">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{cap.name}"/></f:facet>
<f:facet name="input"><p:inputText value="#{cap.name}" style="width: 30%" label="Dénomination"/></f:facet>
</p:cellEditor>
</p:column>

<p:column headerText="Description">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{cap.description}"/></f:facet>
<f:facet name="input"><h:inputText value="#{cap.description}" style="width: 90%" label="Description"/></f:facet>
</p:cellEditor>
</p:column>

<p:column headerText="Réussite obligatoire">
<p:selectBooleanCheckbox value="#{cap.isThresholdOfSuccess}" style="alignment-adjust: central"/>
</p:column>

</p:dataTable>

<p:separator/>

</h:form>
</h:body>


I followed the primefaces demo as well for the bean :

public class EvaluationViewController implements Serializable {
@EJB
private SectionFacade ejbSectionFacade;
private List<Section> currentSections;
private Section currentSection;

@EJB
private UeFacade ejbUeFacade;
private List<Ue> ues;
private Ue ue;

@EJB
private OrganizedUeFacade ejbOrganizedUeFacade;
private List<OrganizedUe> organizedUes;
private OrganizedUe organizedUe;

@EJB
private CapacityFacade ejbCapacity;
private List<Capacity> capacities;
private Capacity capacity;
@PostConstruct
public void init() {
currentSections = ejbSectionFacade.findAll();
ues = new ArrayList<>();
organizedUes = new ArrayList<>();
capacities = new ArrayList<>();
}

public void onSectionSelected() {
if (currentSection != null && !currentSection.getName().equals("")) {
ues = ejbUeFacade.findBySection(currentSection);
ue = null;
capacity = null;
FacesMessage facesMessage = new FacesMessage("Sélection", currentSection.getName());
FacesContext.getCurrentInstance().addMessage(null, facesMessage);
} else {
ues = null;
}
}

public void onUeSelected() {
if ((currentSection != null && !currentSection.getName().equals(""))
&& (ue != null && !ue.getName().equals(""))) {
organizedUes = ejbOrganizedUeFacade.findByUe(ue);
capacities = ejbCapacity.findByUe(ue);
capacity = null;
FacesMessage facesMessage = new FacesMessage("Sélection de l'UE : ", ue.getName());
FacesContext.getCurrentInstance().addMessage(null, facesMessage);
} else {
organizedUes = null;
}
}

public void listenerCapacitiesUpdate() {
capacities = ejbCapacity.findByUe(ue);
}


The DataTable is updated and rendered but not the last oneMenu. I really don't get it. I would be very gratefull for the answer.

Answer

There are two things at hand here:

  • If you do not provide an explict event, the a default one is taken
  • You cannot add two ajax tags to the same component listening to the same event

So if in this case the default event ajax event of the p:selectOneMenu is change, only the second one will be processed. Adding an explicit event other than change to the first ajax handler will make it work

Off-topic but important things you should normally do debugging issues like this:

  • Find the differences between the two and see and try to make them as identical as possible
  • See if the order plays a role by switching them
  • See if using a different component makes it work
Comments