Today I was triggered by a question on the JDeveloper forum about invoking a popup from a backing bean. Actually some time ago I had to build that solution for one of my customers that needed some kind of confirmation to the user that an action invoked in a dialog popup was succesfull. The flow in this solution was more ore less like this: Invoke a dialog popup –> press ok (or cancel) in the dialog –> if ok was pressed, invoke the dialogListener which contains the actual logic to be executed. In case the action is succesfull, show another popup that tells the user “all is well” in all the other cases do something different.
Usually I would add a show popup behaviour to the component from which the popup has to be invoked. However in this case that is not posisble. The invoking component is another popup, and the only triggertypes that are supported for the <af:showpopupbehaviour> are popupClosed, popupOpened and popupOpening.
The popupClosed would be the rigth triggertype to use but saddly this responds to both the OK and to the Cancel button. It seems that is not possible to differentiate between Ok and Cancel. In case of cancel I don’t want to show the second popup, but show the user the initial page. In case of Ok I need to have control on what happens. To achieve this behaviour I need to invoke the second popup programmatically.
Lets go with this use case.
First I need the following managed bean configuration for binding some page elements.
<managed-bean> <managed-bean-name>PopupBean</managed-bean-name> <managed-bean-class>nl.amis.demo.view.backing.PopupBean</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean>
This is the code for the default page with the inputText bound to a backing bean named PopupBean.
<?xml version='1.0' encoding='windows-1252'?> <jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:af="http://xmlns.oracle.com/adf/faces/rich"> <jsp:directive.page contentType="text/html;charset=windows-1252"/> <f:view> <af:document> <af:form> <af:panelGroupLayout halign="center" valign="middle"> <af:spacer width="50%" height="100"/> <af:commandButton id="justSomeButton" text="Hover Me" inlineStyle="font-size:x-large;"> <af:showPopupBehavior popupId="justSomePopup" triggerType="mouseOver"/> </af:commandButton> <af:popup id="justSomePopup"> <af:dialog title="This is an input dialog"> <af:inputText value="This is just text" binding="#{PopupBean.typedValue}"/> </af:dialog> </af:popup> </af:panelGroupLayout> </af:form> </af:document> </f:view> </jsp:root>
Add a dialog Listener to the dialog and create a method popupAction in the PopupBean.
<af:dialog dialogListener=”#{PopupBean.popupAction}”>
Add the javascript function that opens the confirmation popup to the page.
<f:facet name="metaContainer"> <af:group> <script> function launchConfirmed() { var popup = AdfPage.PAGE.findComponent("confirmMessage"); popup.show(); event.cancel(); } </script> </af:group> </f:facet>
And finally add the confirmation popup
<af:popup id="confirmMessage"> <af:dialog cancelVisible="false" closeIconVisible="false" title="This is a confirmation message"> <af:outputText binding="#{PopupBean.confirmeTypedText}"/> </af:dialog> </af:popup>
Now you are ready to invoke the first popup. Run the page and hover the mouse over the button and the popup will appear. Note that the cancelButton and closeIcon are visible, but using these does not invoke the code in de backing bean.
After clicking OK on this popup you can do some processing and (if successfull) invoke the confirmation popup.
You will need the following code in the popupAction method.
public void popupAction(DialogEvent dialogEvent) { // Do all the processing you need // for now just forward the typed text to the outputText in the second popup. System.out.println("dialogEvent = " + dialogEvent.getOutcome().toString()); confirmeTypedText.setValue(null); confirmeTypedText.setValue("the following text was succesfully processed: " +getTypedValue().getValue()); FacesContext context = FacesContext.getCurrentInstance(); ExtendedRenderKitService service = (ExtendedRenderKitService)Service.getRenderKitService(context, ExtendedRenderKitService.class); service.addScript(context, "launchConfirmed();"); }
The addScript part in this mehod does the trick. It will add a handle to the javascript funtion that invokes the second popup. Run the page again, invoke the first popup, and click OK. The second popup will now be invoked.
Now you have the solution for invoking a popup from a popup or (even better) invoke a popup form a backing bean.
This is a browser popup and not an ADF Javascript popup. Do you have a good use case for using afContext.launchDialog ? If you use ADF Javascript popups you have more control on how the popup is rendered, and besides that, popup blockers will not step in and break your app.
Hi,
I run a popup with afContext.launchDialog, all is ok, but my question is, how can invoke the popup but without close icon in ADF. Thanks.
Sorry by mi english, i not so god in that, XP.
Why not just use a FacesContext.addMessage(clientId, message) in the dialogListener.
hey
Can you please tell me where to insert the facet metaContainer?
Thank you
Angel
PS your source code would be more than helpfull
I tried the above thing. I am getting the below error on browser status bar(!); and the second popup doesn’t open. There is no error in the log.
‘AdfPage.PAGE.findComponent(…)’ is null or not an object.
Although the popup id is there on the jspx page.
It looks like I’ve lost the project with the samplecode somewhere in time. Luckily the codesamples provided in this post should do the trick.
Can you share with me the sample source code?
Thanks
Can you send me your source code?