OverlayPanel: Race condition with embedded components on AJAX-update
See original GitHub issue1) Environment
- PrimeFaces version: 8.0
2) Expected behavior
Components (e.g. p:selectOneMenu
) inside a dynamic overlay (e.g. p:overlayPanel
) with appendTo
should not double the found entries when the jq
property of the component widget is resolved
3) Actual behavior
Due to the appendTo
the DOM of the dynamic overlay may survive the AJAX update which effectively doubles the DOM for a short time. The first instance is at the original position (before it is moved to its appendTo
destination) which was added during the AJAX update and the second instance is the old one which may be outside the updated area.
The SelectOneMenu is refreshed before the OverlayPanel. But the old DOM of the OverlayPanel is removed during the refresh of the OverlayPanel (PrimeFaces.utils.registerDynamicOverlay > widget.addRefreshListener). Therefore the SelectOneMenu finds two DOM representation of its widget for SelectOneMenu#jqId
.
4) Steps to reproduce
- Press button
Alert state ofSelectOneMenu
Output should be size = 1 and label = 1 - Press the button
Update OP
- Press button
Alert state ofSelectOneMenu
Output should be size = 2 and label = 11 which is wrong
5) Sample XHTML
<h:form>
<p:commandButton value="Update OP" process="@this pnlTest" update="pnlTest" />
<h:panelGroup id="pnlTest">
<p:commandButton id="btnTest" value="Open Overlay" type="button" />
<p:overlayPanel id="opTest" for="btnTest" appendTo="@(body)">
<p:selectOneMenu value="#{testBean.selectedTest}" widgetVar="somTest">
<f:selectItem itemLabel="1" itemValue="1" />
</p:selectOneMenu>
</p:overlayPanel>
</h:panelGroup>
<p:commandButton value="Alert state ofSelectOneMenu" type="button" onclick="alert('Size of somTest#jq = ' + PF('somTest').jq.length + '\nSelected Label = ' + PF('somTest').getSelectedLabel())" />
</h:form>
6) Sample bean
@ViewScoped
@Named
public class TestBean implements Serializable {
private Integer _selectedTest;
public Integer getSelectedTest() {
return _selectedTest;
}
public void setSelectedTest(Integer selectedTest) {
_selectedTest = selectedTest;
}
}
I will try to provide a test case
Issue Analytics
- State:
- Created 4 years ago
- Comments:8 (8 by maintainers)
The way to fix this right now without being invasive is to add a
onstart="PF('overlayPanel').destroy();"
to your command button updating the OP. This fixes this specific issue but its a workaround not a fixAgreed but your #2 is a much more invasive fix and would be tricky to test all scenarios but that would be the right place to fix it.