Follow Us on Twitter

Working with popups in ADF

by Marcel Maas on June 14, 2011 · 17 comments

Popups, ADF and browsers is the name of the game in this post. I’ve been developing ADF 11g web applications for some time now and I’ve been running into some issues while working with popups. While the popup mechanism in ADF is easy enough to understand and quite powerful, it has some quirks. This mainly has to do with showing and hiding them.  In this post I will show the various way’s to show and hide popups and what the advantages and disadvantages would be.

Firstly the way we create a popup. This is always the same. We create a “popup” element somewhere in the parent containers page.  Inside this element we can define the contents of the popup. This could be anything. If we would like to perform an action after we are done with the dialog we can use the “dialog” element to specify the actions and display the button’s to initiate these actions.

The hierarchical tree would look like this then:

<!--- pseudoXML -->
<af:popup>
   <af:dialog>
      [contents]
   </af:dialog>
</af:popup>

It might be handy to understand how exactly this popup is being rendered runtime. Essentially the popup is created and exists as soon as you create the page. It is simply hidden so it won’t bother you. So if you have a syntax error in your popup display code this error wil manifest itself when the parent page is being loaded, not when you show the popup. Because you usually want to display the popup without getting a full page refresh the popup will be shown and hidden by using javascript.

So how to interact with the popup?

1. From the JSF page

Showing the popup can be done by using the “showPopupBehavior” element. You create this element as the child of a component that can perform an action, like a button

<!--- pseudoXML -->
<af:commandToolbarButton>
   <af:showPopupBehavior />
</af:commandToolbarButton>

You can use this element to specify which popup needs to be shown and you can set some additional properties to specify where. For example if you set the “alignId” to the id of the button the popup will be shown over this button. If you want even more control you can set “align” property to control if the popup is show before, after, etc.. the button. Don’t forget to set the triggertype property. (in our case to “click”) Or else the popup will not be shown.

Closing the popup is done automatically when you use the “dialog” element and one of it’s buttons is clicked. Now there is another thing you can do using this element. You can perform actions based on which button was clicked. An example:

You have a dialog of the type “okCancel” . This means the popup will get two addtional buttons. One for “Ok” and one for “Cancel”. If we want to do something when one of the buttons is clicked we set the “dialogListener”. This must be a function in a backing bean with a parameter of the type “DialogEvent”. Here is how this function could look like:

public void onDialogClose(DialogEvent dialogEvent) {
    if (dialogEvent.getOutcome().equals(DialogEvent.Outcome.ok)) {
       // do Ok things
    } 
}

2. From Backing Bean code

Now there are situations where you do not want to react on a button but a different kind of event. In those cases it might be handy to be able to show a popup from backing bean code. This might pose for some difficulities since backing beans usually run server-side and not client-side (and that’s where the javascript is). Before 11g you had to jump through some hoops to get the job done.  You had to find the current JSF context, then initiate a render kit to provide a pathway to the javascript and eventually inject javascript for the popup to show.

Like so:

FacesContext context = FacesContext.getCurrentInstance();
ExtendedRenderKitService service = Service.getRenderKitService(context, ExtendedRenderKitService.class);
service.addScript(context, "var popup = AdfPage.PAGE.findComponent('"+DIALOG_CLIENT_ID+"'); popup."+action+"();");
AdfFacesContext.getCurrentInstance().addPartialTarget(dialog);

In the example above the “DIALOG_CLIENT_ID” is the id of the popup and the “action” is “show” or “hide”. The bad news is that the above works in older versions of Internet Explorer, but it fails to close the popup in other browsers such as Firefox. The effect is that when using this code and Firefox it will freeze your screen when trying to close (hide) the popup. You can do nothing but to refresh the page and lose all context.

Now on for the good news:

In 11g there is a function that does the work for you and does so equally well in all browsers I have tested. (Firefox, Chrome and IE)

The code for showing and hiding is as follows:

if (action.equals("show")){
  RichPopup.PopupHints ph = new RichPopup.PopupHints();
  popup.show(ph);
} else {
  popup.hide();
}

In the above case “popup” is in instance of RichPopup which can be bound from the JSF page or looked up using its context. The “PopupHints” essentially do the same as the “showPopupBehaviour”. You specify which popup you want to show and provide an alignment if neccesary. Hiding the popup is now as simple as calling “hide()” on the object.

So to recap and conclude:

When working with popups in adf 11g, try to use the “popup”, “dialog” and “showPopupBehaviour” elements. When it is impossible to do so, use the “popup”, “dialog” and the “popupHints” to controll a popup from your backing beans. In all cases try to avoid the use of the renderkit to inject javascript since this code is dependant on the javascript engine of the browser.

Thats all for now! Happy coding!

 

Working with popups in ADF, 4.4 out of 5 based on 10 ratings

Ratings:
VN:F [1.9.22_1171]
Rating: 4.4/5 (10 votes cast)
Tags: , ,

{ 17 comments… read them below or add one }

Chris Lucernoni June 23, 2011 at 10:15 pm

Hey thanks for this post, it was exactly what i was looking for!

Reply

David August 1, 2011 at 12:56 pm

Hi , thanks for your interesting post
I have a question How do you can manage de dialog events from server side ?
I try to do the next:

When someone clik on button “X”
it shows a dialog to confirm if user want continue or not with the execution of button action.
if the user press “yes” continue the execution of buttom action.

is this possiible?

Thanks for your help

Reply

Marcel Maas August 1, 2011 at 1:25 pm

Hi David!

The first method in my post will do exactly what you want I think. You must use the showDialogBehaviour in combination with the dialog element. You then set the property “type” to “okCancel”.

Using the “dialogListener” property on the dialog element you must then create the “onDialogClose” method as is also specified in the first method of my post. In this method you can then check for the typ of event (ok or cancel) using the DialogEvent.outcome.

So in your usecase when the user clicks button “X” the dialog will be launched with two buttons (Ok or Cancel). When either one of the buttons is clicked it will call the server side code in the “onDialogClose”. In this method you can then start the execution or cancel it.

Hope this helps!

Greetings,

Marcel

Reply

Jaya August 24, 2011 at 1:13 pm

Hi i would like to use popup on clicking an icon using oracle 10g. In 10g there is no tag called popup in ADF. kindly help. On clicking particular icon it should show some information.

Reply

ILya Cyclone November 8, 2011 at 9:40 am

Hello,
That code isn’t correct:

public void onDialogClose(DialogEvent dialogEvent) {
if (dialogEvent.getOutcome().equals(DialogEvent.Outcome.ok)) {
// do Ok things
} else {
// do Cancel things
}
}

With okCancel type Cancel button doesn’t call serverside action.

Reply

Marcel Maas November 8, 2011 at 10:58 am

Hello Ilya,

You might be right about that. I had not tested that part. I checked and there is a Outcome.cancel available. However in 11.1.1.4 this one is deprecated. However it should still be possible to use it. Otherwise you would have to implement your own buttons and handle the events. Then you could close them whenever you would like.

Thanks for the tip!

Greetings

Reply

Kanika February 6, 2012 at 11:05 am

Hi,
I am using OkCancel dialog in my popup.

There is one select one choice dropdown in my dialog and I want to disable the Ok button of the dialog if the select one choice don’t have any item to be selected from it.
Please provide some help to do this.

Thanks

Reply

Marcel Maas February 6, 2012 at 12:46 pm

Hello Kanika,

Ik think the best way to do so and stay within the capabilities of the framework is to not use the dialog or set the property type to none. What you must then do is create the buttons on the popup yourself. Now you have more control over the buttons because you can add partial triggers and event listeners to them. You can then use the code in this blog post to open and close the popup as you wish.

A more thorough explanation:

First remove or disable the dialog (Type = none). Then add the ok and cancel button yourself on the page. Now add a value change listener on the select one choice and set the autosubmit property to true. In the java method that handles the change event you can now enable or disable the buttons if you like. You can add partial triggers to the buttons to show the changes. Beware you might have to set the “clientComponent” property to true when you are adding partial triggers from backing bean code.
Finally you can use the code in this post to close or open the popup.

There is another way, but this would mean writing you own custom javascript to enable or disable the button. You would have to look-up the class/id of the component in the dom-tree with something like FireBug and write the code to enable or disable it. However this is beyond the scope of this blogpost and I am not sure whether it will work.

Perhaps there are more ways to archieve the desired functionality but I believe the first method is the easiest to onderstand and works well.

Good luck!

Reply

Baby April 23, 2012 at 5:41 pm

Hi,
In my application i create popup for create, edit, and delete operations by using and show(oracle.adf.view.rich.component.rich.RichPopup.PopupHints()); method.
In that popup inputDate component is present.
when ever iam clicking that inputDate component it is clearing all the previously entered fields in the popup.
can u plz help to solve this bug?

Iam using JDeveloper 11.1.1.5 version

public static void showPopup(RichPopup popup) {
if (popup != null) {
popup.show(new oracle.adf.view.rich.component.rich.RichPopup.PopupHints());
}
}

Reply

palavi June 8, 2012 at 8:44 am

Hi Marcel
[Jdeveloper 11g Release1]

We have a form and a submit button over it. When i click on the submit button, A loader image (circular rotating transparent PNG image )appears until the next page is opened. but we have displayed that image inside a popup>dialog>> and then the image

Due to which the loading image though transparent takes the look and feel of the DIALOG e.g blue background in the header and footer, shadow around the container etc!

How do we get rid off this?

How can we define a specific class for that particular dialog box and what style can we use so that the other dialogs in the pages are not affected?

Pleaseeee provide a suitable solution on this as this is a high priority issue we are facing :(

Reply

Marcel Maas June 8, 2012 at 9:11 am

Hello Palavi,

I think in your case you will have to create a custom skin and use a style class on that dialog box and then style it using your css. In my blog post about how to integrate JQuery and ADF you can find an example project which also adds a custom skin and skins a panel group layout. The same goes for a dialog. The adf selectors you can find in the oracle documentation. (or just google “adf skin selectors”)

Good luck!

Marcel

Reply

palavi June 8, 2012 at 9:37 am

I have already added a skin file and applied styleclass as dialogstyle to the dialogbox.

IN skin.css
.dialogstyle{
background-color:none !important;
background-image:none !important;
border:none !important;
}

but it isn’t taking this.. :(

Reply

Marcel Maas June 8, 2012 at 9:50 am

You have to make sure to use the right selector for the dialog. Only the styleclass might not be enough. Please look at this page:

http://jdevadf.oracle.com/adf-richclient-demo/docs/skin-selectors.html

Here you can find the af:dialog selectors. So you might have to specifiy you css as:

af|dialog::main .dialogstyle { … }

How exactly you have to setup the selector I cannot tell you, that depends on where you put your style class. You can use firebug to see where your style class ends up and whether your style is applied.

Before you can do so you have to disable the content compression of adf by setting the following property in your web.xml:

org.apache.myfaces.trinidad.DISABLE_CONTENT_COMPRESSION

true

Perhaps this helps you along the way a bit.

Marcel

Reply

diego October 6, 2012 at 4:46 am

HI good tut, but you should post the final code and some images of the working code, can you please help me out where I put the onDialogClose thanks.

Reply

Antony October 26, 2012 at 5:18 pm

Hi Marcel,
Thank you.. this is what I was looking for..

one quick question.
In the below line,

AdfFacesContext.getCurrentInstance().addPartialTarget(dialog);

what is dialog? Your code doesn’t specify where it is coming from

Reply

Antony October 26, 2012 at 10:00 pm

I got it by adding the dialog as bean property.. thanks. It worked !

Reply

Dan November 19, 2012 at 3:12 pm

Hi,

Thanks for the post.
could you help?
I genertaed a function for dialogListener in my bean as I saw in your post.
but I’m getting an error when i’m clicking the ok button:
“dialogListener=”#{mainControlller.onDialogClose}”: java.lang.NullPointerException.

If I try for example

it works and I see the correct value of ‘mainControlller.test’.

any idea?
why do I get this error message?

Thanks a lot!

Reply

Leave a Comment

 

Previous post:

Next post:

About Whitehorses
Company profile
Services
Technology

Whitehorses website

Home page
Whitebooks
Jobs

Follow us
Blog post RSS
Comment RSS
Twitter