2010-02-17 11 views
6

In meiner Anwendung muss ich eine Zeile mit einem Klick auf eine Schaltfläche hinzufügen und diese Schaltfläche wird in allen Zeilen sein. Brauchen Sie Hilfe dabei?Wie fügt man eine Zeile in einer Tabelle in JSF dynamisch hinzu?

Item Class

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; } 
} 

verwalten Bean Klasse

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")); 
} 

} 

JSF Code

<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 oder jsf 2.0? – Bozho

+0

jsf 1.2 mit Apache MyFaces – Hariharbalaji

Antwort

9

Alles, was Sie tun müssen, im Grunde nur in die Tat ist ein leeres Objekt auf das Datenmodell hinter dem value Attribute h:dataTable hinzufügen.

Die gleiche leere Zeile muss jedoch auch in der nachfolgenden Anforderung beibehalten werden. Wenn die Backing-Bean ein Anforderungsbereich ist, wird das Datenmodell ohne die leere Zeile erneut geladen. Dies alles sollte funktionieren, wenn die Bean im Session-Bereich ist.

Außerdem gibt es mehrere Fehler in Ihrem JSF-Code. Das h:dataTablevar Attribut fehlt und der Spalteninhalt muss in einem h:column sein.

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

A Sitzung oder Ansicht scoped Bohne wie folgt aussehen:

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; 
    } 
} 

Die Item Klasse natürlich eine Standard haben sollte kein argument Konstruktor. Normalerweise ist dies bereits implizit verfügbar. Wenn Sie jedoch einen eigenen Konstruktor mit Argumenten definieren, ist dieser nicht mehr verfügbar. Sie müssen es explizit definieren, sonst können Sie Item item = new Item(); nicht mehr tun.

public class Item { 

    private String value; 

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

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

    // ... 
} 

Wenn Sie die Bohnen in dem Anfrage Umfang halten bevorzugen, dann müssen Sie die Menge an neu hinzugefügten Elemente erhalten, so dass die Bohne die gleiche Menge an Belastung bewahren kann.

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()); 
     } 
    } 
} 

Sie werden nur noch die folgenden auf die <h:form> der JSF-Seite hinzuzufügen:

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

Weitere Erkenntnisse über die Verwendung von Datentabellen in irgendeiner Weise Sie diesen Artikel nützlich finden können: Using Datatables. Es enthält auch eine WAR-Datei mit vielen Beispielen sowohl im Anforderungs- als auch im Sitzungsumfang.

+0

@BalusC: Ich habe Zweifel in dieser Technik, wenn ich den Knopf drücke, wird die ganze Seite richtig aufgefrischt, können wir das Ganze mit Ajax machen, so dass dieser Prozess asynchron ist. – Hariharbalaji

+0

Ja, Sie können. Da Sie JSF 2.0 noch nicht verwenden, müssen Sie einige Komponentenbibliotheken von Drittanbietern hinzufügen. Ich kann Ihnen die Unterkomponente Ajax4jsf von JBoss RichFaces empfehlen. Um mehr zu erfahren: http://www.jboss.org/file-access/default/members/jbossajax4jsf/freezone/docs/devguide/en/html_single/index.html – BalusC

+0

Mit dem von Ihnen zur Verfügung gestellten Link habe ich versucht, das zu ändern Code, um ajax zu unterstützen. Ich bekomme einen Fehler, der '# {myMB.addItem}' Methode nicht gefunden: .... Aber ich habe diese Methode in der Bean-Klasse. Ich habe meinen Code editiert ... Kindly Help – Hariharbalaji

2

Nehmen Sie diese Tabelle als Beispiel:

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

Die Methode myBean.addRow wird einfach ein neues Element in der Liste hinzufügen:

public class MyBean { 

    private List<SomeClass> list; 

    ... 

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

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

Wann werden Sie auf den Button klicken wird die Methode addRow ein neues Element in der Liste hinzufügen. Die Seite wird aktualisiert und zeigt die Tabelle mit einer neuen Zeile an.

Edit:

In Bezug auf Ihre Post Auflage, drei Dinge:

Punkt 1: Könnten Sie bitte den Stacktrace Ihrer Fehler anhängen?

Punkt 2: Ihre Methode addRow gibt eine String zurück, eine ID, die von JSF für die Navigation verwendet wird. Da diese Aktion keine Navigation mit sich bringt (dh der Benutzer Aufenthalt auf der gleichen Seite), bringen Sie einfach null oder "":

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

Punkt 3: Ich schlage vor, dass Sie Ihre Klasse Item einen leeren Konstruktor bereitstellen (zusätzlich Ihre aktuellen Konstruktor):

public Item() { 
} 
+0

In Zeile 2 der Bean-Klasse haben Sie SomeElement erwähnt und in der Getter-Methode haben Sie SomeClass erwähnt ... Können Sie klären – Hariharbalaji

+0

Sorry, es war nur ein Tippfehler. Ich habe meinen Beitrag bearbeitet. Natürlich verwende ich die gleiche Art von Objekt (da Sie kein Code-Snippet bereitgestellt haben, habe ich einige Annahmen getroffen, was Sie in Ihrer JSF-Seite und Bean haben). – romaintaz

+0

Hi ich habe den my code angehängt, bekomme aber error.Can u Help. – Hariharbalaji