Here's a quick and easy way to dynamically add JSF components to a page. You'll need a jsp, a backing bean, and a jsf component library. On the jsp, you will need a button and "container component" (I used a PanelGrid) with a binding to a backing bean. The button will call a method on the backing bean. The method will add child UI components to the bound container component.
1. The jsp. Notice the container component (PanelGrid) has a binding to the backing bean. The button calls the "addComponents" method on the backing bean.
<html xmlns:jsp="http://java.sun.com/JSP/Page"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:c="http://java.sun.com/jstl/core"
xmlns:ice="http://www.icesoft.com/icefaces/component"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns="http://www.w3.org/1999/xhtml">
<jsp:directive.page contentType="text/html"/>
<ui:composition>
<ice:panelGrid binding="#{backingBean.containerComponent}"/>
<br/>
<ice:commandButton value="Add UI Components" action="#{backingBean.addComponents}" partialSubmit="true"/>
</ui:composition>
</html>
2. The backing bean. The addComponents method makes a call to a database to determine what/how many fields need to be added to the container component.
import com.icesoft.faces.component.ext.HtmlPanelGrid;
import com.icesoft.faces.component.ext.UIColumn;
import com.icesoft.faces.component.ext.HtmlOutputText;
import com.icesoft.faces.component.ext.HtmlInputText;
public class BackingBean {
private HtmlPanelGrid containerComponent;
public void addComponent() {
//clean previous component
containerComponent.getChildren().clear();
List<Node> nodes = nodeDao.getAllNodes();
//dynamically add Child Components to Container Component
for (Node node : nodes) {
UIColumn col = new UIColumn();
HtmlOutputText ot = new HtmlOutputText();
ot.setValue(node.getLabel() + ": ");
col.getChildren().add(ot);
HtmlInputText it = new HtmlInputText();
it.setValue("");
it.setId(node.getLabel());
col.getChildren().add(it);
if (containerComponent == null) {
containerComponent = new HtmlPanelGrid();
}
containerComponent.getChildren().add(col);
}
}
public HtmlPanelGrid getContainerComponent() {
return containerComponent;
}
public void setContainerComponent(HtmlPanelGrid containerComponent) {
this.containerComponent = containerComponent;
}
}
That's it!
7 Comments
Leave a comment
0 TrackBacks
Listed below are links to blogs that reference this entry: JSF - Dynamically Adding UIComponents To A Form.
TrackBack URL for this entry: http://www.nearinfinity.com/mt/mt-tb.cgi/420



Hi
this thing doesn't work when i binded a panel
to a htmlPanel variable in backing and doing this
Backing Bean is as below
i think i am not able to bind the rich panel
with the HtmlPanel form
because when it is using the add component
the form is null
import org.richfaces.component.html.HtmlPanel;
public class BackingBean {
private HtmlPanel form;
public void addComponents(){
form.getChildren().clear();
if(form == null){
form = new HtmlPanel();
}
HtmlCalendar calender = new HtmlCalendar();
form.getChildren().add(calender);
}
public HtmlPanel getForm() {
return form;
}
public void setForm(HtmlPanel form) {
this.form = form;
}
}
help me how to do this
Hi.
I have used the code and works perfect. I had to make a change, form.getChildren().clear(); form = null
Now I'm facing problems to make a valueBinding to my regular method.
thanks
Hi,
Not sure if this thread is alive but, how do you get the value of the inputText once someone has entered text into it?
Thanks
Rory
Rory,
You'll need to iterate over the children of "HtmlPanelGrid containerComponent". It contains UIColumns which contains HtmlInputText components.
Hope this helps,
Mike
worked perfectly, thanks a lot!
how can i use this without a nodeDao. currently onm my set up I am not using DAO.
whats nodeDao? i mean is it a Data Access Object? if it is how can i implement this with out using DAO?