Как динамически добавить строку в таблицу в JSF?
-
21-09-2019 - |
Вопрос
В моем приложении мне нужно добавить строку одним нажатием кнопки, и эта кнопка будет во всех строках.Нужна помощь, чтобы сделать это?
Класс предмета
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; }
}
Управление классом компонента
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-код
<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>
Решение
Все, что вам нужно сделать, это просто добавить пустой объект в модель данных за value
атрибут h:dataTable
.
Но эту же пустую строку необходимо сохранить и в последующем запросе.Если резервный компонент находится в области запроса, то модель данных перезагружается без пустой строки.Все это должно работать, когда bean-компонент ограничен сеансом.
Кроме того, в вашем коде JSF есть несколько ошибок.А h:dataTable
var
атрибут отсутствует, а содержимое столбца должно находиться внутри 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>
А в области сеанса или представления bean может выглядеть так:
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;
}
}
А Item
класс, конечно, должен иметь конструктор без аргументов по умолчанию.Обычно это уже неявно доступно, но если вы определите свой собственный конструктор с аргументами, он больше не будет доступен.Вам нужно будет явно определить это, иначе вы не сможете сделать Item item = new Item();
больше.
public class Item {
private String value;
public Item() {
// Keep default constructor alive.
}
public Item(String value) {
this.value = value;
}
// ...
}
Если вы предпочитаете хранить бобы в объем запроса, то вам нужно будет поддерживать количество вновь добавленных элементов, чтобы компонент мог сохранять то же количество при загрузке.
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());
}
}
}
Вам нужно будет только добавить следующее в <h:form>
страницы JSF:
<h:inputHidden binding="#{bean.count}" converter="javax.faces.Integer" />
Для получения дополнительной информации об использовании таблиц данных вы можете найти эту статью полезной: Использование таблиц данных.Он также содержит файл WAR с множеством примеров как в области запроса, так и в области сеанса.
Другие советы
Возьмите эту таблицу в качестве примера:
<h:datatable value="#{myBean.list}" ...>
...
<h:column>
<h:commandButton value="Add a row" action="#{myBean.addRow}"/>
</h:column>
</h:datatable>
Метод myBean.addRow просто добавит новый элемент в ваш список:
public class MyBean {
private List<SomeClass> list;
...
public List<SomeClass> getList() {
return list;
}
public void addRow() {
list.add(new SomeClass());
}
}
Когда вы нажмете на кнопку, метод Добавить ряд добавит новый элемент в список.Страница обновится и отобразит таблицу с новой строкой.
Редактировать:
Что касается вашего поста, три вещи:
Пункт 1: Не могли бы вы приложить трассировку стека вашей ошибки?
Пункт 2: Ваш метод addRow возвращает String
это идентификатор, используемый JSF для навигации.Поскольку это действие не предполагает никакой навигации (т.пользователь остается на той же странице), просто вернитесь null
или ""
:
public String addRow() {
list.add(new Item("new data"));
return null;
}
Пункт 3: Я предлагаю вашему классу Item
укажите пустой конструктор (в дополнение к вашему текущему конструктору):
public Item() {
}