ADF弹窗取消监听器在带错误值关闭对话框时未触发
popupCanceledListener not triggered when closing ADF popup by clicking outside the dialog Problem Scenario
When entering a negative value into the af:inputText inside your ADF dialog popup, the validator throws the error "Negative numbers not allowed" and the input gets a red error border. However, when you close the popup by clicking outside of it (expecting to reset the input), the inputText doesn't reset. The popupCanceledListener only gets invoked when pressing the Esc key or clicking the OK button—those are the only times the input resets correctly.
Relevant Code
JSF Markup
<af:popup contentDelivery="lazyUncached" autoCancel="enabled" popupCanceledListener="#{pageFlowScope.testBean.handleResetPopup}" childCreation="deferred" id="testPopup"> <af:dialog type="none" modal="false" id="Dlg1"> <af:inputText label="DECIMAL PLACES" columns="2" validator="#{pageFlowScope.testBean.validateDecimalPlaceValue}" value="#{pageFlowScope.testBean.decimalPlace}" id="input1" autoSubmit="true"></af:inputText> <f:facet name="acceptNFChange"> <af:commandButton text="OK" id="cb1" actionListener="#{pageFlowScope.testBean.handleOkFromPopup}" partialSubmit="true"></af:commandButton> </f:facet> </af:dialog> </af:popup>
Backing Bean Code
public void handleResetPopup(PopupCanceledEvent popupCanceledEvent) { try { UIComponent component = popupCanceledEvent.getComponent(); RichInputText inputText = (RichInputText)JSFUtil.findComponent(component, "input1"); inputText.resetValue(); } catch (Throwable th) { this.handleException(th); } }
Why This Happens
The core issue is with your non-modal dialog (modal="false"). When autoCancel="enabled" is set on the popup, clicking outside the dialog closes the popup, but this doesn't fire the popupCanceledEvent by default. This event is only triggered for explicit cancellation actions—like pressing the Esc key or using a dedicated cancel button—not for outside clicks on non-modal popups.
Fixes You Can Implement
Here are two reliable solutions depending on your use case:
Option 1: Add Client-Side Logic to Trigger Server-Side Reset
We'll listen for the popup's popupClosed event, detect if it was closed via an outside click, and manually trigger your reset logic using a hidden command button.
- Update your popup's JSF markup to include a client listener and hidden button:
<af:popup contentDelivery="lazyUncached" autoCancel="enabled" popupCanceledListener="#{pageFlowScope.testBean.handleResetPopup}" childCreation="deferred" id="testPopup"> <af:clientListener method="handlePopupClosed" type="popupClosed"/> <af:dialog type="none" modal="false" id="Dlg1"> <af:inputText label="DECIMAL PLACES" columns="2" validator="#{pageFlowScope.testBean.validateDecimalPlaceValue}" value="#{pageFlowScope.testBean.decimalPlace}" id="input1" autoSubmit="true"></af:inputText> <f:facet name="acceptNFChange"> <af:commandButton text="OK" id="cb1" actionListener="#{pageFlowScope.testBean.handleOkFromPopup}" partialSubmit="true"></af:commandButton> </f:facet> </af:dialog> <!-- Hidden button to trigger the reset logic --> <af:commandButton id="hiddenResetBtn" partialSubmit="true" actionListener="#{pageFlowScope.testBean.handleResetPopup}" style="display:none;"/> </af:popup>
- Add this JavaScript function to your page (use
<af:resource type="javascript">to include it):
function handlePopupClosed(event) { const popup = event.getSource(); // Check if the popup closed due to an outside click (auto-cancel) if (event.getReason() === AdfRichPopup.CLOSE_REASON_AUTO_CANCEL) { // Find the hidden button and trigger it to run the reset logic const resetBtn = popup.findComponent("hiddenResetBtn"); if (resetBtn) { resetBtn.click(); } } }
Option 2: Switch to a Modal Dialog (If Permitted)
If your workflow allows a modal dialog, changing modal="true" on the af:dialog will make outside clicks block interaction (by default) and when combined with autoCancel="enabled", closing via outside click will fire the popupCanceledEvent. Simply update the dialog tag:
<af:dialog type="none" modal="true" id="Dlg1">
How to Verify
After applying either fix:
- Enter a negative value into the input to trigger the validation error.
- Close the popup by clicking outside it.
- Reopen the popup: the input should be reset to its initial state, with no red error border.
内容的提问来源于stack exchange,提问作者TheGaME

