This morning I received an email from a reader of one of my articles on the blog. The challenge in the email: I want to programmatically create an input field. Then I want to add a showpopup behavior to this input field – to have a popup display when the field is hovered over with the mouse. It turns out that the ShowPopupBehavior is not a UIComponent that you can simply add a child to another UIComponent. So could it be done and if so, how?
A little investigation made clear
that RichInputText, the component class for the Rich InputText component, has a method getClientListeners() (as well as setClientListeners()). When you specify a showPopupBehavior tag in the JSPX file, it is turned into a client side behavior object that is registered in this set of ClientListeners. To programmatically create showpopupbehavior, we have to manipulate this set. Note: all RichInput components seem to have the get/setClientListeners methods; they are not inherited from a common superclass.
The code required in the use case for my emailing reader now turns out to be quite simple.
With this JSF page:
<?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 binding="#{PageManager.form}"> <af:popup id="myPopup"> <af:panelWindow title="The Popup"/> </af:popup> </af:form> </af:document> </f:view> </jsp:root>
The backing bean has this code:
package nl.amis.view; import java.util.Set; import oracle.adf.view.rich.component.rich.RichForm; import oracle.adf.view.rich.component.rich.input.RichInputText; import oracle.adf.view.rich.event.ClientListenerSet; public class PageManager { private RichForm form; public PageManager() { } public void setForm(RichForm form) { RichInputText newText = new RichInputText(); newText.setLabel("new Text"); newText.setId("newText1"); ClientListenerSet set = newText.getClientListeners();
if (set == null) {
set = new ClientListenerSet();
newText.setClientListeners(set);
}
set.addBehavior("new AdfShowPopupBehavior('myPopup',AdfRichPopup.ALIGN_AFTER_END,null,'mouseOver')");
form.getChildren().add(newText); this.form = form; } public RichForm getForm() { return form; } }
It creates the rich inputText along with the behavior to display a Popup when hovered over:
Mandy is correct in the respect that the utilisation of more resources could cause issues with heavy user-load.
Annotations work, I think you can use four different types. I tried out your idea of change listener and that seems to be more effective but uses more resources so could be a problem if you have a lot of users on a page.
Hi Lucas,
Good article. I have a similar problem where i have to show pop up dynamically based on the user input on Input Text field.
Do you think i can use the same solution on the value change listener of Input text.
According to 1.2 specification following annotations should works im managed bean:
@PostConstruct
@PreDestroy
It should works for managed beans with request, session and application scopes.
Hi Jakub
That looks very elegant. Does that annotation work in managed beans? I have not used it before.
Lucas.
Hi Lucas,
Nice solution. I think, instead using setter Form method, more elegant would be:
@PostConstruct
public void createPopup(){
// popup code
}
what do you think?