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_1
My 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