Follow by Email

Saturday, 16 May 2015

Apply ActionListener to programmatically created buttons/link in ADF


This post is next in series of "Working with ADF Faces Components programmatically"
Previous posts are-
Creating dynamic layout (form and UI Component) using ADF Faces
Get Value from programmatically created components , Iterate over parent component to get child values in ADF Faces

Now this post is about applying ActionListener to a programmatically created button or link
Let's start (Jdev 12.13) -

  • First created a FusionWebApplication and a page in viewController project
  • Dropped a button on page , on this button action i will create a link programmatically and assign actionListener to it
  • To create new link i have added following code (described in previous posts)



  •     /**Method to add dynamically created component to a parent layout
         * @param parentUIComponent
         * @param childUIComponent
         */
        public void addComponent(UIComponent parentUIComponent, UIComponent childUIComponent) {
            parentUIComponent.getChildren().add(childUIComponent);
            AdfFacesContext.getCurrentInstance().addPartialTarget(parentUIComponent);
        }
    

           //Creating Link programmatically on button click     
            RichLink ui = new RichLink();
            ui.setId("li1");
            ui.setText("Programmatically Created Link");
            ui.setInlineStyle("font-weight:bold;");
            //Add this link to parent form layout
     //ParentGroupLayoutBind is the component binding of panelGroupLayout
            addComponent(getParentGroupLayoutBind(), ui);
    

  • After this we are able to create a new Link on click of button, now next is to assign ActionListener to this Link
    For this first i have to define an ActionListener method in bean. So i have added this 

  •     /**Action Listener to be applied on dynamically created button
         * @param actionEvent
         */
        public void actionForProgLink(ActionEvent actionEvent) {
            FacesMessage infoMsg = new FacesMessage("Action Listener Invoked");
            infoMsg.setSeverity(FacesMessage.SEVERITY_INFO);
            FacesContext.getCurrentInstance().addMessage(null, infoMsg);
        }
    

  • Now how to assign this ActionListener to that dynamically created Link?
    See the Code-

  •     /**Method to to resolve actionListener
         * @param actionName
         */
        private ActionListener getActionListener(String actionName) {
            //here Testbean is the name of ManagedBean
            MethodExpression methodExp = getMethodExpressionForAction("#{viewScope.Testbean." + actionName + "}");
            return new MethodExpressionActionListener(methodExp);
        }
    

    Helper method to resolve ActionListener-

        private MethodExpression getMethodExpressionForAction(String actionName) {
            Class[] argtypes = new Class[1];
            argtypes[0] = ActionEvent.class;
    
            FacesContext facesCtx = FacesContext.getCurrentInstance();
            Application app = facesCtx.getApplication();
            ExpressionFactory elFactory = app.getExpressionFactory();
            ELContext elContext = facesCtx.getELContext();
            return elFactory.createMethodExpression(elContext, actionName, null, argtypes);
        }
    

    Just pass the name of method to resolve it

       //Apply ActionListener on this dynamically created link 
        ui.addActionListener(getActionListener("actionForProgLink")); 
     
Now time to check , run application :)
First a button appears-


On click of this button a link is created -

Click on this link- programmatically assigned Action Listener is called

Cheers , Happy Learning :)

8 comments :

  1. Hi Ashish. Great series!!!

    I am currently having to do something exactly along these lines - programmatically creating a number of buttons and to each of these buttons add event behavior (mouseOver, actionListener, contextMenu). However, in addition to having an actionListener to perform one action, I want to provide a right-click context menu of additional options where each menu-item is tied to its own actionListener. The difficulty that I am having is once the menu is rendered and the actionListener for the menu-item invoked, I cannot get the id of the component from which the right-click used to present the context-menu, was generated.

    Have you done anything along these lines or do you have any suggestions about how it might be accomplished.

    Thanks - Steve.

    ReplyDelete
    Replies
    1. Hi Steve

      I have never tried something like this but whenever i'll get time i'll try to do this

      Ashish

      Delete
  2. Hi Ashish. Well I found the solution at http://jdevadf.oracle.com/adf-richclient-demo/docs/tagdoc/af_popup.html which uses the setPropertyListener in combination with setting the eventContext and launcherVar attributes of the popup. In the actionListener, the selectedButton value can be pulled from pageFlowScope.

    Here is the code.










    Thanks for your help and keep up great blogging.

    Steve.

    ReplyDelete
  3. hi
    I want to create multiple links and each link is taking different action based on id of each link
    how can i do these

    ReplyDelete
    Replies
    1. You have everything in managed bean so you can create links programmatically and in same way add actionlistener to it

      Delete
    2. public void actionForProgLink(ActionEvent actionEvent) {


      }
      in these method i want to get the id of links that created in button
      how i can do that???????????

      Delete
    3. I don't understand the use case exactly ?
      You can get clicked link id using actionEvent.getComponent().getClientId() code

      Ashish

      Delete