Please disable your adblock and script blockers to view this page

Search this blog

Friday, 29 May 2015

Apply Client/Server listener to programmatically created components, apply JavaScript to ADF Faces components at run time

Hello All

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 
Apply ActionListener to programmatically created buttons/link in ADF

Now this post is about applying client listener & server listener (to execute some javascript function) to a programmatically created component (inputText, outputText etc)

Let's see the implementation part (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 an inputText programmatically
  • To create new inputText 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);
        }
    


            //Code to create af:inputText and add it to panelgroup layout
            RichInputText ui = new RichInputText();
            ui.setValue("Programmatically Created Input Text");
            ui.setId("pit1");
            ui.setContentStyle("width:200px;color:navy");
            //getParentGroupLayoutBind is the component binding of parent panel group layout
            addComponent(getParentGroupLayoutBind(), ui);
    

  • Now first part is done - Creation of input text , next is to assign client and server listener to it
    So for that first we have to add some JavaScript function in page that will be called using clientListener
    I have added this JavaScript function in page, it just fires a custom event from client and pass component value as parameter

  •         function demoJsFunction(evt){
              var comp = evt.getSource();
              alert(comp);
              AdfCustomEvent.queue(comp, "ServerEventToGetValue", {fvalue:comp.getSubmittedValue()}, true);
              evt.cancel();
            }
          
    

  • One more thing is to define server listener method in managed bean so that we can apply it to inputText at run time

  •     /**Server Listener - It will be called on execution of client side javascript
         * @param clientEvent
         */
        public void testServerListener(ClientEvent clientEvent) {
            //To get value passed from Client Event
            String val = clientEvent.getParameters().get("fvalue").toString();
            FacesMessage msg=new FacesMessage("Server Listener Called and value in inputText is - " + val);
            msg.setSeverity(FacesMessage.SEVERITY_INFO);
            FacesContext.getCurrentInstance().addMessage(null, msg);
           
        }
    

  • Now create clientListener/ServerListener programmatically and assign both to inputText
    Pass server listener method name along with managed bean name

  •         // Create new Client Listener and assign method name and type
            ClientListenerSet CL = new ClientListenerSet();
            CL.addListener("click", "demoJsFunction");
            //Add Server listener , assign client event name and resolve pre-defined serverlistener
            CL.addCustomServerListener("ServerEventToGetValue",
                                       getMethodExpression("#{viewScope.Testbean.testServerListener}"));
    
            // Add clientListener/ServeListener to inputText
            ui.setClientComponent(true);
            ui.setClientListeners(CL);
    

    Helper method to resolve expression-

        /**To Resolve ServerListener method
         * @param s
         * @return
         */
        public MethodExpression getMethodExpression(String s) {
    
            FacesContext fc = FacesContext.getCurrentInstance();
            ELContext elctx = fc.getELContext();
            ExpressionFactory elFactory = fc.getApplication().getExpressionFactory();
            MethodExpression methodExpr = elFactory.createMethodExpression(elctx, s, null, new Class[] {
                                                                           ClientEvent.class });
            return methodExpr;
    
        }
    

  • All done , now run application and check , click on button it will create a inputText
         now click on input text and see server listener is called :)

This is how we can apply javascript in programmatic created components
Cheers :) Happy Learning

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 :)

Wednesday, 6 May 2015

Get Value from programmatically created components , Iterate over parent component to get child values in ADF Faces

Sometimes we need to create and add ADF Faces components at runtime , we can do it programmatically
I have posted about this before
Creating dynamic layout (form and UI Component) using ADF Faces

Now this post talks about getting value from programmatically created component, means when user enters value in those component then how to access that value in managed bean

Here i am using Jdev 12.1.3 , Let's see the implementation part

Created a page and added two buttons , one to create component at run time and second one to get values from those components
See page XML source code -

<af:document title="ProgComponent.jspx" id="d1">
            <af:form id="f1">
                <af:spacer width="10" height="10" id="s3"/>
                <af:button text="Create Components " id="b1"
                           actionListener="#{viewScope.GetValueProgCompBean.createComponentsAction}"/>
                <af:spacer width="10" height="10" id="s1"/>
                <af:button text="Get Value" id="b2"
                           actionListener="#{viewScope.GetValueProgCompBean.getValueOfCompAction}"/>
                <af:panelGroupLayout id="pgl1" layout="vertical"
                                     binding="#{viewScope.GetValueProgCompBean.parentGroupBind}">
                    <af:spacer width="10" height="10" id="s2"/>
                </af:panelGroupLayout>
            </af:form>
        </af:document>

To create components at run time i have used same approach described in above blog post
Check the code written on Create Components button



import javax.faces.component.UIComponent;
import javax.faces.event.ActionEvent;

import oracle.adf.view.rich.component.rich.input.RichInputText;
import oracle.adf.view.rich.component.rich.layout.RichPanelGroupLayout;
import oracle.adf.view.rich.context.AdfFacesContext;


    //Binding of panel group layout , it will be parent of prog. created components
    private RichPanelGroupLayout parentGroupBind;

    public void setParentGroupBind(RichPanelGroupLayout parentGroupBind) {
        this.parentGroupBind = parentGroupBind;
    }

    public RichPanelGroupLayout getParentGroupBind() {
        return parentGroupBind;
    }

    /**Method to add child components to parent
     * @param parentUIComponent
     * @param childUIComponent
     */
    public void addComponent(UIComponent parentUIComponent, UIComponent childUIComponent) {
        parentUIComponent.getChildren().add(childUIComponent);
        AdfFacesContext.getCurrentInstance().addPartialTarget(parentUIComponent);
    }

    /**Method to create Input text at run time
     * @param actionEvent
     */
    public void createComponentsAction(ActionEvent actionEvent) {
        //Create an Object of desired UI Component
        RichInputText ui = new RichInputText();
        //Set properties
        ui.setId("rit1");
        ui.setLabel("Input text 1");
        ui.setContentStyle("font-weight:bold;color:red");
        //Now add this component to any parent component
        addComponent(getParentGroupBind(), ui);

        RichInputText ui1 = new RichInputText();
        ui1.setId("rit2");
        ui1.setLabel("Input text 2");
        ui1.setContentStyle("font-weight:bold;color:red");
        addComponent(getParentGroupBind(), ui1);
    }

Now run application and click on button , you will see two inputText are created


Now to get value of these components follow the steps
1. Get Parent layout
2. Iterate over parent to get all child components
3. Get Value of every child

See the code written on get value button in managed bean

    /**Method to Iterate over parent and get value of all child components
     * @param actionEvent
     */
    public void getValueOfCompAction(ActionEvent actionEvent) {
        RichPanelGroupLayout PF = getParentGroupBind(); // Get Parent Layout
        List<UIComponent> listcomp = PF.getChildren(); // Get all child
        Iterator iter = listcomp.iterator(); // Create an Iteraotr to iterate over childs
        while (iter.hasNext()) {
            UIComponent comp = (UIComponent) iter.next(); // Get next Child Component
            System.out.println("Component is-" + comp + " and value is-" +
                               comp.getAttributes().get("value")); //Get Component detial and it's value
        }
    }

Again check , enter value in both inputText and click on button to get value


Output on console-

Sample ADF Application- Download
Cheers :) Happy Learning