2010-02-17 26 views
6

En mi aplicación necesito agregar una fila al hacer clic en un botón y este botón estará en todas las filas. ¿Necesitas ayuda para hacer esto?¿Cómo agregar dinámicamente una fila en una tabla en JSF?

clase de artículos

public class Item { 
public Item() 
{ 

} 
private String value; 
public Item(String value) { this.value = value; } 
public void setValue(String value) { this.value = value; } 
public String getValue() { return value; } 
} 

de Bean Clase

public class MyMB 
{ 
private List<Item> list;  

public void addItem() { // JSF action method 
    list.add(new Item("Default")); 
    Iterator<Item> iterator = list.iterator(); 
    while(iterator.hasNext()) 
    { 
     Item item = (Item)iterator.next(); 
     System.out.println(item.getValue()); 
    } 
    System.out.println(); 
    } 
/** 
* @return the list 
*/ 
public List<Item> getList() { 
    if(list==null) 
    { 
     loadList(); 
    } 
    return list; 
} 
private void loadList() { 
    list = new ArrayList<Item>(); 
    list.add(new Item("Data")); 
} 

} 

código JSF

<h:form> 
    <rich:dataTable value="#{myMB.list}" var="item" id="tabel"> 
    <h:column><h:inputText value="#{item.value}" /></h:column> 
    <h:column><a4j:commandButton value="Add" actionListener="#{myMB.addItem}" reRender="tabel"/></h:column> 

+0

jsf 1.2 o jsf 2.0? – Bozho

+0

jsf 1.2 con Apache MyFaces – Hariharbalaji

Respuesta

9

Todo lo que necesita hacer es, básicamente, de hecho, sólo añadir un objeto vacío con el modelo de datos detrás del atributo value de h:dataTable.

Pero la misma fila vacía debe conservarse en la solicitud posterior también. Si el bean de respaldo tiene un alcance de solicitud, entonces el modelo de datos se vuelve a cargar sin la fila vacía. Todo esto debería funcionar cuando el bean tenga una sesión de alcance.

Además, hay varios errores en el código JSF. Falta el atributo h:dataTablevar y el contenido de la columna debe estar dentro de un h:column.

<h:form> 
    <h:dataTable value="#{bean.list}" var="item"> 
     <h:column><h:inputText value="#{item.value}" /></h:column> 
    </h:dataTable> 
    <h:commandButton value="Add" action="#{bean.add}"/> 
</h:form> 

Una sesión o ver scoped frijol puede tener este aspecto:

public class Bean { 
    private List<Item> list; 

    public Bean() { 
     list = new ArrayList<Item>(); 
    } 

    public void add() { 
     list.add(new Item()); 
    } 

    public List<Item> getList() { 
     return list; 
    } 
} 

La clase Item debe por supuesto tener un constructor sin argumentos por defecto. Normalmente, esto ya está disponible implícitamente, pero si defines tu propio constructor con argumentos, ya no estará disponible. Necesitarás definirlo explícitamente, de lo contrario ya no podrás hacer Item item = new Item();.

public class Item { 

    private String value; 

    public Item() { 
     // Keep default constructor alive. 
    } 

    public Item(String value) { 
     this.value = value; 
    } 

    // ... 
} 

Si prefiere mantener el grano en el ámbito solicitud, entonces usted tendrá que mantener la cantidad de artículos que acaba de agregar, de manera que el grano puede conservar la misma cantidad de carga.

public class Bean { 
    private List<Item> list; 
    private HtmlInputHidden count = new HtmlInputHidden(); 

    public Bean() { 
     count.setValue(0); 
    } 

    public void add() { 
     list.add(new Item()); 
    } 

    public List<Item> getList() { 
     if (list == null) loadList(); 
     return list; 
    } 

    public HtmlInputHidden getCount() { 
     return count; 
    } 

    public void setCount(HtmlInputHidden count) { 
     this.count = count; 
    } 

    private void loadList() { 
     list = new ArrayList<Item>(); 

     // Preserve list with newly added items. 
     for (int i = 0; i < (Integer) count.getValue(); i++) { 
      list.add(new Item()); 
     } 
    } 
} 

Sólo tendrá que añadir lo siguiente a la <h:form> de la página JSF:

<h:inputHidden binding="#{bean.count}" converter="javax.faces.Integer" /> 

Para obtener más ideas sobre el uso de tablas de datos en cualquier forma que puede encontrar este artículo útil: Using Datatables. También contiene un archivo WAR con muchos ejemplos tanto en el alcance de la solicitud como en el de la sesión.

+0

@BalusC: Tengo una duda en esta técnica, cuando presiono el botón toda la página se actualiza correctamente, podemos hacer todo esto usando Ajax para que este proceso sea asincrónico. – Hariharbalaji

+0

Sí, puedes. Como todavía no está utilizando JSF 2.0, deberá conectar una biblioteca de componentes de terceros. Le puedo recomendar el subcomponente Ajax4jsf de JBoss RichFaces. Para obtener más información: http://www.jboss.org/file-access/default/members/jbossajax4jsf/freezone/docs/devguide/en/html_single/index.html – BalusC

+0

Con el enlace proporcionado por usted, traté de cambiar el código para admitir ajax.Estoy recibiendo un error que '# {myMB.addItem}' Método no encontrado: .... Pero tengo ese método en la clase Bean. He editado mi código ... Amablemente Ayuda – Hariharbalaji

2

Tome esta tabla como ejemplo:

<h:datatable value="#{myBean.list}" ...> 
    ... 
    <h:column> 
     <h:commandButton value="Add a row" action="#{myBean.addRow}"/> 
    </h:column> 
</h:datatable> 

El método myBean.addRow simplemente añadir un nuevo elemento en la lista:

public class MyBean { 

    private List<SomeClass> list; 

    ... 

    public List<SomeClass> getList() { 
     return list; 
    } 

    public void addRow() { 
     list.add(new SomeClass()); 
    } 
} 

Cuando se haga clic en el botón , el método addRow agregará un nuevo elemento en la lista . La página actualizará y mostrará la tabla con una nueva fila.

Editar:

Con respecto a su edición posterior, tres cosas:

Punto 1: Podría por favor incluya la StackTrace de su error?

Punto 2: Su método addRow devuelve un String que es una identificación utilizada por JSF para la navegación. Ya que esta acción no implica ninguna de navegación (es decir, la estancia del usuario en la misma página), devuelva null o "":

public String addRow() { 
    list.add(new Item("new data")); 
    return null; 
} 

Punto 3: que sugieren que la clase Item proporcionar un constructor vacío (además de su constructor actual):

public Item() { 
} 
+0

En la línea 2 de la clase Bean has mencionado SomeElement y en el método getter has mencionado SomeClass ... ¿Puedes aclarar – Hariharbalaji

+0

? Lo siento, fue solo un error tipográfico. Edité mi publicación. Por supuesto, utilizo el mismo tipo de objeto (ya que no proporcionó ningún fragmento de código, hice algunas suposiciones sobre lo que tiene en su página JSF y bean). – romaintaz

+0

Hola, he adjuntado mi código, pero estoy recibiendo un error. Puede ayudarme. – Hariharbalaji

Cuestiones relacionadas