Follow by Email

Monday, 5 August 2013

Creating dynamic layout (form and UI Component) using ADF Faces

hello all,
today i had a scenario to create UI Components at run time and i tried to do that on my ADF page.
searched lot in Google and finally all summary is in post.

Suppose you have to create UI Components (input text, buttons, check-boxes etc ) or form (set of multiple UI Components) at runtime - follow these steps

  • Find a parent component to create child under it as any layout (panel form, panel group, af:form etc)
  • Suppose you have a page with a panel form layout, now you have to create child components in this form layout at runtime
  • Bind this form layout to managed bean

  • <af:panelFormLayout id="pfl1" rows="2" binding="#{DynamicCompBean.panelFormLay}"/>
    

  • Now thanks to Mahmoud A. Elsayed for this method, that adds child component to parent component

  •     public void addComponent(UIComponent parentUIComponent, UIComponent childUIComponent) {
            parentUIComponent.getChildren().add(childUIComponent);
            AdfFacesContext.getCurrentInstance().addPartialTarget(parentUIComponent);
        }
    

  • you can call this method , wherever you want to create UI Component and add it to page .



  • Now i have created a button on page and a radio box to select which component should be created
  • Now on button click , i have generated components conditionally based on selection
  • To generate any component - see managed bean code to create input text

  •             RichInputText ui = new RichInputText();
                ui.setId("rit1");
                ui.setLabel("Input text");
                ui.setValue("Hello ADF");
                ui.setContentStyle("font-weight:bold;color:red");
    

  • same as this ,for other component i have written code and set their properties in managed bean
  • look at managed bean code-

  • package dynamic.view.bean;
    
    import java.io.Serializable;
    
    import javax.faces.component.UIComponent;
    import javax.faces.event.ActionEvent;
    
    import oracle.adf.view.rich.component.rich.RichForm;
    import oracle.adf.view.rich.component.rich.input.RichInputText;
    import oracle.adf.view.rich.component.rich.input.RichSelectBooleanCheckbox;
    import oracle.adf.view.rich.component.rich.input.RichSelectOneRadio;
    import oracle.adf.view.rich.component.rich.layout.RichPanelFormLayout;
    import oracle.adf.view.rich.component.rich.nav.RichCommandButton;
    import oracle.adf.view.rich.component.rich.output.RichOutputText;
    import oracle.adf.view.rich.context.AdfFacesContext;
    
    public class DynamicCompBean implements Serializable {
    
        /**Parent component to add childs in it*/
        private RichPanelFormLayout panelFormLay;
    
        /**Binding to select which component should be created*/
        private RichSelectOneRadio compTypeBind;
    
        public DynamicCompBean() {
        }
    
        /**Method to add child to parent component*/
        public void addComponent(UIComponent parentUIComponent, UIComponent childUIComponent) {
            parentUIComponent.getChildren().add(childUIComponent);
            AdfFacesContext.getCurrentInstance().addPartialTarget(parentUIComponent);
        }
    
        /**Button code to generate and add components conditionally*/
        public void createComptext(ActionEvent actionEvent) {
    
            if (compTypeBind.getValue().toString().equalsIgnoreCase("I")) {
                RichInputText ui = new RichInputText();
                ui.setId("rit1");
                ui.setLabel("Input text");
                ui.setValue("Hello ADF");
                ui.setContentStyle("font-weight:bold;color:red");
                addComponent(getPanelFormLay(), ui);
            } else if (compTypeBind.getValue().toString().equalsIgnoreCase("O")) {
                RichOutputText ui = new RichOutputText();
                ui.setId("rot1");
                ui.setValue("I am output text");
                ui.setInlineStyle("font-weight:bold;color:green");
                addComponent(getPanelFormLay(), ui);
            } else if (compTypeBind.getValue().toString().equalsIgnoreCase("C")) {
                RichSelectBooleanCheckbox ui = new RichSelectBooleanCheckbox();
                ui.setId("ch1");
                ui.setValue(true);
                ui.setLabel("CheckBox");
                addComponent(getPanelFormLay(), ui);
            } else if (compTypeBind.getValue().toString().equalsIgnoreCase("B")) {
                RichCommandButton ui = new RichCommandButton();
                ui.setId("ch1");
                ui.setText("Button");
                ui.setInlineStyle("font-weight:bold;");
                addComponent(getPanelFormLay(), ui);
            }
    
        }
    
    
        public void setPanelFormLay(RichPanelFormLayout panelFormLay) {
            this.panelFormLay = panelFormLay;
        }
    
        public RichPanelFormLayout getPanelFormLay() {
            return panelFormLay;
        }
    
        public void setCompTypeBind(RichSelectOneRadio compTypeBind) {
            this.compTypeBind = compTypeBind;
        }
    
        public RichSelectOneRadio getCompTypeBind() {
            return compTypeBind;
        }
    }
    

  • Now run this application and select input text to create-

  • Select others also and create a form

  • You can create complex forms using this

         Download Sample workspace-Download Sample

6 comments :

  1. Hello Ashish,
    Thanks for your sharing.
    I still have a quick question. Can we do this before page loaded?

    ReplyDelete
    Replies
    1. Yes you can do but component bindings are not accessible before page load so you have to use some trick
      Create a variable in bean and generate it's accessors and bind this variable to any page component and write code to create new component in getter method

      Ashish

      Delete
  2. Hi Ashish,
    Nice article.
    Is it possible remove the created component using another function?

    ReplyDelete
    Replies
    1. You can set rendered false for components like this

      ui.setRendered(false);

      Delete
  3. Hi Ashish,

    Is it possible to control the values, for example, of the inputText or a selectOneChoice, to obtain programmatically the value that was added or chosen?

    For example, I have a value, and if I edit one inputText and put a smaller value I want to add a new section (input text, select one choice) until the remaining value is 0.

    ReplyDelete
  4. Yes you can get values in bean and write your code using conditions
    Check - Get Value from programmatically created components

    Ashish

    ReplyDelete