Dynamic components
aalves Apr 14, 2009 3:12 AMHello,
I am a newbie on Jboss seam, and I have a problem trying to create fields on forms dynamically, I have seen several examples but it does not work.
I get the following exception when I try to render the page:
javax.faces.FacesException: javax.el.ELException: /crearActividad.xhtml @23,64 binding="#{crearActividad.containerComponent}": Error reading 'containerComponent' on type com.tresw.reservas.session.CrearActividad_$$_javassist_1My Action class is as follows:
package com.tresw.reservas.session;
import java.util.LinkedList;
import java.util.List;
import org.jboss.seam.annotations.Begin;
import org.jboss.seam.annotations.Factory;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Out;
import org.jboss.seam.log.Log;
import org.jboss.seam.international.StatusMessages;
import org.richfaces.component.html.HtmlComboBox;
import org.hibernate.validator.Length;
import com.tresw.reservas.entity.Tipocampo;
import javax.faces.component.UIColumn;
import javax.faces.component.UISelectItems;
import javax.faces.component.html.HtmlInputText;
import javax.faces.component.html.HtmlOutputText;
import javax.faces.component.html.HtmlPanelGrid;
import javax.faces.model.SelectItem;
@Name("crearActividad")
public class CrearActividad
{
@Logger private Log log;
@In StatusMessages statusMessages;
private String value;
@In(required = false, create = true)
@Out
private HtmlPanelGrid containerComponent;
public void crearActividad()
{
// implement your business logic here
log.info("crearActividad.crearActividad() action called with: #{crearActividad.value}");
statusMessages.add("crearActividad #{crearActividad.value}");
}
public HtmlPanelGrid getContainerComponent() {
return containerComponent;
}
public void setContainerComponent(HtmlPanelGrid containerComponent) {
this.containerComponent = containerComponent;
}
@Length(max = 10)
public String getValue()
{
return value;
}
public void setValue(String value)
{
this.value = value;
}
public List<SelectItem> getSelectItem()
{
List<Tipocampo> campos = new TipocampoList().getResultList();
List<SelectItem> result = new LinkedList<SelectItem>();
for(Tipocampo campo : campos)
{
SelectItem item = new SelectItem(campo.getId().intValue(),campo.getTipo());
result.add(item);
}
return result;
}
public List<Tipocampo> getItems()
{
List<Tipocampo> campos = new TipocampoList().getResultList();
return campos;
}
public void addComponents() {
//clean previous component
containerComponent.getChildren().clear();
int nodes = Integer.parseInt(value);
//dynamically add Child Components to Container Component
for (int i=0;i<nodes; i++)
{
UIColumn col = new UIColumn();
HtmlOutputText ot = new HtmlOutputText();
ot.setValue("Nombre del campo" + ": ");
col.getChildren().add(ot);
HtmlInputText it = new HtmlInputText();
it.setValue("");
it.setId("nombre"+i);
col.getChildren().add(it);
UIColumn col2 = new UIColumn();
HtmlOutputText ot2 = new HtmlOutputText();
ot2.setValue("Tipo del campo" + ": ");
col2.getChildren().add(ot2);
HtmlComboBox combo = new HtmlComboBox();
UISelectItems items = new UISelectItems();
items.setValue(items);
combo.getChildren().add(items);
col2.getChildren().add(combo);
if (containerComponent == null) {
containerComponent = new HtmlPanelGrid();
}
containerComponent.getChildren().add(col);
containerComponent.getChildren().add(col2);
}
}
@Factory("containerComponent")
@Begin(join = true)
public void start()
{
containerComponent = new HtmlPanelGrid();
}
}
And my page is as follows:
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:s="http://jboss.com/products/seam/taglib"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:rich="http://richfaces.org/rich"
xmlns:a="http://richfaces.org/a4j"
template="layout/template.xhtml">
<ui:define name="body">
<h:form id="crearActividadForm">
<rich:panel>
<f:facet name="header">crearActividad</f:facet>
<s:decorate id="valueField" template="layout/edit.xhtml">
<ui:define name="label">Value</ui:define>
<h:inputText id="value" required="true" value="#{crearActividad.value}"/>
</s:decorate>
<h:panelGrid binding="#{crearActividad.containerComponent}">
<h:commandButton value="Anadir campos" action="#{crearActividad.addComponents}" partialSubmit="true"/>
</h:panelGrid>
<div style="clear:both"/>
</rich:panel>
<div class="actionButtons">
<h:commandButton id="crearActividad" value="crearActividad"
action="#{crearActividad.crearActividad}"/>
</div>
</h:form>
</ui:define>
</ui:composition>
Can anybody help me?
Or give me an example on how generating the form dynamically?
thanks in advance