X

The Mobile & Digital Assistant Blog covers the latest in mobile and conversational AI development and engagement

How-to open and close a popup dialog from Java in MAF

Frank Nimphius
Master Principal Product Manager

 

MAF Version: 2.1

Problem
Statement

In MAF, application
developers use two component behavior tags,
amx:showPopupBehavior and amx:closePopupBehavior, to show or hide popup dialogs in
response to user interaction, pressing a command button or link. What however
if you need to show or hide a popup from Java in a value change listener or
similar component event? And what if the dialog should close itself after a
period of time? By the time of writing, no API for this exists in MAF.

The Solution

Since there is no
framework API to close and open popup dialogs in MAF, a custom implementation must do. The custom implementation uses JavaScript, as well as the
amx:showPopupBehavior and amx:closePopupBehavior tags on hidden buttons (visible
buttons would be possible too).

To show or hide a popup dialog you use Java in
a managed bean to call out to JavaScript,using the
AdfmfContainerUtilities.invokeContainerJavaScriptFunction() framework method.

Section Q&A:

Q1: Could you call the
same from a POJO Data Control?
A1:Yes you can.

Q2: Does it make sense?
A2: No. The data
control is part pf the MAF model and thus needs to be generic and not
specifically written for a view in MAF. 

About
the Example Code

The MAF 2.1 sample
code shown in this blog entry (and available for download) keeps it simple. The
AMX page displays single command button that, when pressed, triggers a
component action event. This action event is calls a Java method in a managed
bean that in turn invokes JavaScript to "virtually" press the hidden
button with the
amx:showPopupBehavior tag attached to it for you. A timer in
the same managed bean then waits for 5 seconds before it closes the dialog,
pressing the other hidden button (it actually raises a tap event on teh
button). Its a simple example that however showcases nicely how you can open
and clode dialogs in MAF.

The
Sample Implementation

Though you can
download the sample ZIP file from a link provided at the end of this article,
its worth showing the code in the blog entry as well, so you you can quickly
scan it. The JavaScript source is saved in a stand-alone JS file so it can be
reused. In general I recommend using external JavaScript files and force
yourself to write generic code than to stuff scripts into an AMX page directly.

Step 1) Creating the
JavaScript file

First you need to create JavaScript file - or extend an
existing file - with the JavaScript code shown below. In my sample (MAF 2.1)
this the JS file is named "PopupUtils.js". The two functions in the
file
popupUtilsShowPopup
and popupUtilsHidePopup become
globally available for the feature they are configured for (explained next).
The two functions require a singel argument to be passed, which is the id of
the popup dialog to close

(function () {
  //register 
  popupUtilsShowPopup = function() {
        //the argument is required and cannot be missing
        if (arguments.length > 0) {
            var popupOpener = document.getElementById(arguments[0]);
            if (popupOpener != null && popupOpener != undefined) {
                adf.mf.api.amx.triggerBubbleEventListener(popupOpener,"tap");
            }
            else {
                adf.mf.log.Application.logp(adf.mf.log.level.WARNING,
                  "PopupUtils", "showPopup", "hidden button to launch
                   popup not found");
            }
        }
        else {
            adf.mf.log.Application.logp(adf.mf.log.level.WARNING,
              "PopupUtils", "showPopup", "Missing input argument");
        }
    }

    popupUtilsHidePopup = function() {
        //the argument is required and cannot be missing
        if (arguments.length > 0) {
            var popupCloser = document.getElementById(arguments[0]);

            if (popupCloser != null && popupCloser != undefined) {
                adf.mf.api.amx.triggerBubbleEventListener(popupCloser,"tap");
            }
            else {
                adf.mf.log.Application.logp(adf.mf.log.level.WARNING,
                "PopupUtils","showPopup", "hidden button to close popup
                 not found");
            }
        }
        else {
            adf.mf.log.Application.logp(adf.mf.log.level.WARNING,
             "PopupUtils", "hidePopup", "Missing input argument");
        }
    }

})();

Step 2) Registering
the JS file with a MAF feature

To register the JavaScript file with a MAF feature, open the
maf-feature.xml
file (the file resides in the View Controller| Application Sources || META-INF
directory). In the opened maf-feature.xml file, select the feature that needs
programmatic access to a popup and select the "Content" tab. Click
the green plus icon next to the "Includes" label and search for the
JavaScript file in the project. The file type should be set to
"JavaScript".

With this configuration, the custom JavaScript
functions become available so they can be called from AdfmfContainerUtilities.invokeContainerJavaScriptFunction()

Step 3) About the
Managed Bean (Java)

A managed bean is useed to hold the Java code that either
launches or closes the popup. The managed bean doesn't hold state and therefore
can be defined in any scope (shorter scopes are preferred). The sample actually
shows and hides the popup in response to an action performed on another button.
However, you can call the same code from any other component event, e.g. from a
value change listener.

public class PopupHelper {

    boolean isPopupOpen = false;

    public PopupHelper() {

    }

    public void onPopupShowHideAction(ActionEvent actionEvent) {

        if (!isPopupOpen) {

         //the error object is filled with the reason for a JS exception.
         //If the variable is empty, no exception has occured. Note that
         //usually you use the return object to pass information from the
         //JS function back to MAF. In this case, the function doesn't
         //return a value and so its only used here to allow debugging
         //of exceptions

            Object errorMsg =
                AdfmfContainerUtilities.invokeContainerJavaScriptFunction
                (FeatureContext.getCurrentFeatureId(),"popupUtilsShowPopup",
                new Object[] {"_popShowId" });


            isPopupOpen = true;

            //wait a few seconds and then close the popup
            Timer timer = new Timer();
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                  closePopup();
                  this.cancel();
                }

            },5000);

        }
            }


    private void closePopup() {

        if (isPopupOpen) {

            Object errorMsg =
               AdfmfContainerUtilities.invokeContainerJavaScriptFunction(
                FeatureContext.getCurrentFeatureId(),"popupUtilsHidePopup",
                new Object[] {"_popCloseId" });
            isPopupOpen = false;

        }

    }
}

Step 4) Configuring
the hidden buttons

The hidden buttons
(in this example they are hidden, but can be visible too) have the two behavior
tags, amx:showPopupBehavior and amx:closePopupBehavior defined as shown in the
AMX page source shown below

<amx:panelPage>
 ...
  <amx:commandButton text="_hiddenShow" id="_popShowId"
                     inlineStyle="visibility: hidden;">
      <amx:showPopupBehavior id="spb1" popupId="p1"
                        type="action" decoration="simple" alignId="pp1"
                        align="overlapMiddleCenter"/>
  </amx:commandButton>
  <amx:commandButton text="_hiddenClose" id="_popCloseId"
                      inlineStyle="visibility: hidden;">
      <amx:closePopupBehavior id="cpb1" popupId="p1"
                                     type="action"/>
  </amx:commandButton>



  <amx:commandButton text="Show / Hide Popup" id="cb3"
                     actionListener="#{PopupHelper.onPopupShowHideAction}"/>

</amx:panelPage>
  <amx:popup id="p1" autoDismiss="false"
          inlineStyle="font-size:large;">
          <amx:outputText value="This Popup is launched from Java in a
                         managed bean. Wait 5 seconds for Java to close
                          this dialog." id="ot2"/>
</amx:popup> 

Download
Sample

The sample files can
be downloaded in a MAF 2.1 workspace from here:
http://www.oracle.com/technetwork/developer-tools/adf/learnmore/programmaticcloseofpopup-2420222.zip Run the AMX page within the sample workspace and press the command button in
the opened mobile application. A dialog shows and stay up for 5 seconds before
it closes down again.

Note:  If you experience problems, or like
to comment on the solution, please post to the MAF forum on OTN:
https://community.oracle.com/community/oracle-mobile/oraclemaf/content?customTheme=otn

Join the discussion

Comments ( 2 )
  • guest Thursday, February 19, 2015

    Its help


  • AurelienPer Tuesday, June 30, 2015

    Very helpfull post. Thanks

    But I have a problem for the align middle center as describe in my post in Oracle Forum https://community.oracle.com/thread/3758191?sr=inbox

    Can you help me to fix it?


Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.

Recent Content