2010-02-17 17 views
6

W mojej aplikacji muszę dodać wiersz za jednym kliknięciem przycisku, a ten przycisk będzie we wszystkich wierszach. Potrzebujesz pomocy, aby to zrobić?Jak dynamicznie dodawać wiersz w tabeli w JSF?

klasy Item

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

Zarządzaj Bean Class

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

} 

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

+0

jsf 1.2 z Apache MyFaces – Hariharbalaji

Odpowiedz

9

Wszystko, co musisz zrobić, to w zasadzie rzeczywiście tylko dodanie pustego obiektu do datamodel za atrybut h:dataTablevalue.

Ale ten sam pusty wiersz musi zostać zachowany także w kolejnym żądaniu. Jeśli komponent bean backbacku ma zasięg scentrowany, wówczas przeładowuje się datownik bez pustego wiersza. To wszystko powinno działać, gdy komponent bean ma zasięg sesji.

Dalej jest kilka błędów w twoim kodzie JSF. Brakuje atrybutu h:dataTablevar, a zawartość kolumny musi znajdować się wewnątrz 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> 

sesja lub widok scoped fasola może wyglądać następująco:

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

Klasa Item oczywiście powinna mieć wartość domyślną no-Arg konstruktora. Zwykle jest to już niejawnie dostępne, ale jeśli zdefiniujesz własny konstruktor z argumentami, to nie będzie on już dostępny. Musisz go jawnie zdefiniować, w przeciwnym razie nie będziesz już mógł wykonywać Item item = new Item();.

public class Item { 

    private String value; 

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

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

    // ... 
} 

Jeśli wolisz, aby utrzymać fasolkę w zakresie żądanie, to trzeba utrzymać ilość nowo dodanych elementów, tak, że fasola może zachować taką samą kwotę na obciążenia.

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

Musisz tylko dodać następujące do <h:form> strony JSF:

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

żeby uzyskać więcej informacji na temat korzystania z DataTables w jakikolwiek sposób może przydać: Using Datatables. Zawiera również plik WAR z wieloma przykładami zarówno w zakresie żądania, jak i sesji.

+0

@BalusC: Mam wątpliwości w tej technice, kiedy naciskam przycisk, cała strona jest odświeżana, czy możemy zrobić to wszystko za pomocą Ajax, aby ten proces był asynchroniczny. – Hariharbalaji

+0

Tak, możesz. Ponieważ nie korzystasz jeszcze z JSF 2.0, musisz podłączyć bibliotekę komponentów innych firm. Mogę polecić ci składnik Ajax4jsf z JBoss RichFaces. Aby dowiedzieć się więcej: http://www.jboss.org/file-access/default/members/jbossajax4jsf/freezone/docs/devguide/en/html_single/index.html – BalusC

+0

Za pomocą podanego przez Ciebie linku próbowałem zmienić kod do obsługi ajax.I otrzymuję błąd, że "# {myMB.addItem}" Nie znaleziono metody: .... Ale mam tę metodę w klasie Bean. Zmodyfikowałem swój kod ... Uprzejmie pomoc – Hariharbalaji

2

Take tej tabeli jako przykład:

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

Metoda myBean.addRow po prostu dodać nowy element na liście:

public class MyBean { 

    private List<SomeClass> list; 

    ... 

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

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

Kiedy klikniesz na przycisku , metoda addRow doda nowy element do listy . Strona zostanie odświeżona i wyświetli tabelę z nowym wierszem.

Edit:

Odnośnie swojej edycji postu, trzy rzeczy:

Punkt 1: mógłbyś dołączyć StackTrace swojego błędu?

Punkt 2: Twoja metoda addRow zwraca String, która jest identyfikatorem używanym przez JSF do nawigacji. Ponieważ działanie to nie pociąga za sobą żadnych nawigacji (czyli pobytu użytkownika na tej samej stronie), po prostu wrócić null lub "":

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

punktu 3: I sugerują, że twoja klasa Item dostarczyć pusty konstruktor (oprócz od aktualnej konstruktora):

public Item() { 
} 
+0

W linii 2 klasy Bean wspomniałeś SomeElement iw metodzie getera wspomniałeś SomeClass ... Możesz wyjaśnić – Hariharbalaji

+0

Niestety, to był tylko literówka. Zmodyfikowałem mój post. Oczywiście używam tego samego rodzaju obiektu (ponieważ nie dostarczyłeś żadnego fragmentu kodu, założyłem pewne założenia dotyczące tego, co masz na swojej stronie i fasoli JSF). – romaintaz

+0

Witam Mam załączony mój kod, ale otrzymuję błąd. Możesz pomóc. – Hariharbalaji