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

11 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
  5. Hi Ashsish,

    can we change Header text dynamically in result table fields on UI based on LOV selected in Search form.

    ReplyDelete
    Replies
    1. You can put condition in headerText attribute and change values according to condition using Expression

      Delete
  6. Hi Ashsish
    You are always a creative person
    I have a question :
    suppose I want to store the values of those component into database table,every UI Value in a new row in this table how could we do that?

    ReplyDelete
    Replies
    1. Thanks Mariam

      You can get value from programmatically created components and then you can insert a row in viewObject and set values
      Check Get Value from programmatically created components , Iterate over parent component to get child values in ADF Faces

      Ashish

      Delete
  7. Hi Ashish,
    Can I dynamically create forms on the page using the method that you just explained here.
    I am trying to create a UI where first I have a create form of a parent object and then a check box to show up 3 additional create forms which has the child object.

    ReplyDelete