Adding JSF components Dynamically    Jan 5, 2010

It is interesting to be able to Add to the JSF page components dynamically.

I am Using Oracle ADF was curious how to do it, If you are curious too, it is simple

1- I created a JSF page by dragging a data control component as a Form

2- I created a bean with the following code

import oracle.adf.view.faces.component.core.layout.CorePanelForm;
import oracle.adf.view.faces.component.core.nav.CoreCommandButton;
 

public class ggggg
{
    private CorePanelForm panelform;
    public ggggg() {
}

public String commandButton_action()   
 {
    CoreCommandButton button = new CoreCommandButton();
    button.setText("hello");
    panelform.getChildren().add(button);  // this will add a button to the Panel Form
return null;
}


public void setPanelform(CorePanelForm panelform)
{
this.panelform = panelform;
}
public CorePanelForm getPanelform()
{
return panelform;
}
}

 

the example below shows the output after invoking commandButton 1 which runs the code above
 

 

 

Jan 9, 2010

 

i found the following link with yet more details about the same topic

 

http://wiki.apache.org/myfaces/Programmatic

 

repeated her for convenience

 

Programmatic manipulation of the components

This page is for those developers who would like to create JSF-based UIs programmatically. It covers dynamic creation of components and components trees in the runtime.

 

The problem

Most people who use JSF build static UIs. That is, they write JSPs or Facelets pages explicitly defining the UIs. Such a page typically consists of a number of tags which actually create the component tree.

In case of dynamic component creation you don't know the structure of your page in advance and therefore you can't describe it in any static way. You simply can't design a JSP or Facelets XHTML or anything similar because you simply do not know, which components will make up your page, in which order, and what the structure will be.

The example of such scenario is any model-driven UI. Imagine you'd like to implement a generic bean editor. You know how to edit string, number, date or whatever properties, but the structure of the generic bean is not known in advance. Therefor you will need to build your component subtree in the runtime.

Building component structures in the runtime has quite a lot of peculiarities. We'll try to gather the information on this topic in this page. It's community driven, so if you have an idea, a recipe or and advise, please feel free to append.

 

Creating and binding components

To make your dynamic component structures be visible to the end-user, you basically need to do the following:

  1. Implement a backing bean that creates the component structure and exposes it via a property.
  2. Bind a component to this property in the JSP or Facelets page.

  <h:panelGrid binding="#{someBean.dynamicPanelGrid}"/>

The someBean object then needs to provide a method to create and populate the dynamic component. WARNING: the code below is untested.

  private HtmlPanelGrid grid; 

  public HtmlPanelGrid getDynamicPanelGrid() {
    if (grid == null) {
      Application app = FacesContext.getCurrentInstance().getApplication();
      grid = (HtmlPanelGrid) app.createComponent(HtmlPanelGrid.COMPONENT_TYPE);

      HtmlOutputText text = (HtmlOutputText) app.createComponent(HtmlOutputText.COMPONENT_TYPE);
      text.setValue("some text");
      grid.getChildren().add(text);
    }

    return grid;
  }

When the presentation page is initially processed (whether JSP, Facelets or other), the specified binding will first be read; if not null then the returned component is used instead of one being created. Providing a getter method therefore ensures that your code creates the component rather than it being created via the presentation page. Note that all properties (other than the binding) specified in the presentation page are ignored if you do this.

If you want the dynamic part of your page to be generated only as a result of the user selecting an action (eg performing a database search causes dynamic creation of components to display the results) then you can instead define a binding and provide only a setter method, then in the action method modify the component:

  <h:panelGrid binding="#{someBean.dynamicPanelGrid}"/>

  private HtmlPanelGrid grid; 

  public void setDynamicPanelGrid(UIComponent component) {
    this.grid = (HtmlPanelGrid) component;
  }

  public String doSomeAction() {
      grid.getChildren().clear();

      Application app = FacesContext.getCurrentInstance().getApplication();
      HtmlOutputText text = (HtmlOutputText) app.createComponent(HtmlOutputText.COMPONENT_TYPE);
      text.setValue("some text");
      grid.getChildren().add(text);

      return "someActionSuccess";
    }
  }

The Apache Shale ViewController can also be used; its page-based callbacks are convenient places in which to configure dynamic components.