已编辑:没有完整的信息。
我使用Prime Faces 6.2创建带有选中列的数据表。
<p:dataTable id="#{prefix}List"
value="#{tickets}"
lazy="true"
paginator="true"
paginatorTemplate="{FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}"
currentPageReportTemplate="{startRecord}-{endRecord} из {totalRecords}"
rows="20"
rowKey="#{ticket.id}"
var="ticket"
emptyMessage="Записи в данной категории отсутствуют">
<p:ajax event="toggleSelect" listener="#{ticketForm.onAllSelect}" process="@this" partialSubmit="true" />
<p:ajax event="rowSelectCheckbox" listener="#{ticketForm.onSelect}" update=":protocolForm" />
<p:ajax event="rowUnselectCheckbox" listener="#{ticketForm.onUnselect}" update=":protocolForm" />
<p:ajax event="rowSelect" listener="#{ticketForm.onSelect}" update=":protocolForm" />
<p:ajax event="rowUnselect" listener="#{ticketForm.onUnselect}" update=":protocolForm" />
<p:column selectionMode="multiple" style="width:40px; text-align:center" />
更具体地说,当选中标题复选框时,我想在服务器端接收所有选定的行数据,并使用每行的ID。同样,当选择至少一个复选框时,逻辑可以帮助解决隐藏/渲染页面按钮的目标。为此,我需要手动拦截行/复选框选择事件并在按下按钮时从中记录ID,因此无法使用这种逻辑使用dataTable的selection
属性。
在服务器端,我有几个事件监听器。 :
private Set<AbstractMTSBUExportTicket> abstractMTSBUExportTickets = new HashSet<>();
public Set<AbstractMTSBUExportTicket> getAbstractMTSBUExportTickets() {
return abstractMTSBUExportTickets;
}
public void onSelect(SelectEvent event) {
abstractMTSBUExportTickets.add((AbstractMTSBUExportTicket) event.getObject());
}
public void onUnselect(UnselectEvent event) {
abstractMTSBUExportTickets.remove(event.getObject());
}
public void onAllSelect(ToggleSelectEvent event) {
// do smth
}
不幸的是,ToggleSelectEvent里面只有关于数据表本身的信息。我找不到有关行的信息。我也尝试添加process="@this" partialSubmit="true"
属性,但似乎它们执行不同的操作。
那么,您能否举例说明如何从事件对象中检索此类数据?我应该使用另一种方法来解决吗?感谢您的提前答复。
答案 0 :(得分:1)
我认为您在数据表上缺少一些东西。
展示:https://www.primefaces.org/showcase/ui/data/datatable/selection.xhtml
您需要添加selectionMode = multiple和selection = collection来收集所选行,例如...
<p:dataTable id="multipleDT"
var="car"
value="#{dtSelectionView.cars4}"
selectionMode="multiple"
selection="#{dtSelectionView.selectedCars}"
rowKey="#{car.id}">
无论您选择一行还是多行,#{dtSelectionView.selectedCars}集合都会自动填充选定的行。
答案 1 :(得分:0)
您使用的是懒惰的dataTable,这并不会停留在页面更改上。
您需要使用集合类型设置selection
参数
在getRowKey
内插入LazyDataModel
并删除rowKey="#{ticket.id}"
带有复选框的选择不需要selectionMode="multiple"
。
XHTML文件:
<p:dataTable id="#{prefix}List"
value="#{tickets}"
lazy="true"
paginator="true"
var="ticket"
selection="#{ticketForm.selectedTickets}"
emptyMessage="Записи в данной категории отсутствуют">
<p:ajax event="toggleSelect"
listener="#{ticketForm.onAllSelect}" partialSubmit="true"/>
<p:ajax event="rowSelectCheckbox"
listener="#{ticketForm.onSelect}" update=":protocolForm"/>
<p:ajax event="rowUnselectCheckbox"
listener="#{ticketForm.onUnselect}" update=":protocolForm"/>
<p:ajax event="rowSelect"
listener="#{ticketForm.onSelect}" update=":protocolForm"/>
<p:ajax event="rowUnselect"
listener="#{ticketForm.onUnselect}" update=":protocolForm"/>
<p:column selectionMode="multiple" style="width:40px; text-align:center" />
<!--other p:columns-->
</p:dataTable>
托管bean:
public void onRowSelect(SelectEvent event) {
if (event != null && event.getObject() != null &&
event.getObject() instanceof Ticket) {
if (selectedTickets== null) {
selectedTickets= new ArrayList<Ticket>();
}
if (!selectedTickets.contains((Ticket) event.getObject())) {
selectedTickets.add((Ticket) event.getObject());
}
}
}
public void onRowUnselect(UnselectEvent event) {
if (event != null && event.getObject() != null &&
event.getObject() instanceof Ticket &&
selectedTickets != null && selectedTickets.contains((Ticket) event.getObject())) {
selectedTickets.remove((Ticket) event.getObject());
}
}
public void onAllRowsSelect(ToggleSelectEvent event) {
//This is the trick, you don't need receive a collection
if (event.isSelected()) {
selectedTickets = ticketService.getAllTickets();
} else {
selectedTickets = new ArrayList<Ticket>();
}
}
LazyDataModel
方法getRowKey
的实现:
public class LazyPragaModel extends LazyDataModel<Ticket> implements Serializable {
private TicketService ticketService;
private static final long serialVersionUID = 1L;
public LazyPragaModel(TicketService ticketService) {
this.ticketService= ticketService;
}
@Override
public Object getRowKey(Ticket ticket) {
return ticket!= null ? ticket.getId() : null;
}
@Override
public Praga getRowData(String rowKey) {
List<Ticket> tickets = (List<Ticket>) getWrappedData();
for (Ticket ticket: tickets) {
if (ticket.getId().toString().endsWith(rowKey)) {
return ticket;
}
}
return null;
}
@Override
public List<Ticket> load(int first, int pageSize, String sortField,
SortOrder sortOrder, Map<String, Object> filters) {
setRowCount(ticketService.countLazyRecords(filters).intValue());
List<Ticket> tickets = ticketService.listLazyRecords(first, pageSize,
sortField, sortOrder.name(), filters);
return tickets;
}
}
为您服务的摘要。惰性数据表的通用方法:
public List<T> listLazyRecords(int first, int pageSize, String sortField,
String sortOrder, Map<String, Object> filters) {
sortOrder = sortOrder != null ? sortOrder.contains("ASC") ? "ASC" :
sortOrder.contains("DESC") ? "DESC" : null : null;
String query = " FROM " + getType().getSimpleName() + " t " +
(filters.size() > 0 ? buildLazyFilters(filters) : "") +
(sortOrder != null ? " ORDER BY " + sortField + " " + sortOrder : "");
return getManager().createQuery(query, getType())
.setFirstResult(first).setMaxResults(pageSize).getResultList();
}
public Long countLazyRecords(Map<String, Object> filters) {
String query = "SELECT COUNT(x) FROM " + getType().getSimpleName() +
" x " + (filters.size() > 0 ? buildLazyFilters(filters) : "");
return getManager().createQuery(query).getSingleResult();
}
private String buildLazyFilters(Map<String, Object> filters) {
StringBuilder filterBuild = new StringBuilder("WHERE ");
for (Map.Entry<String, Object> filter : filters.entrySet()) {
if (filter.getValue().toString().chars().allMatch(Character::isDigit)) {
filterBuild.append("( " + filter.getKey() + " = " +
filter.getValue() + " OR ");
}
filterBuild.append(filter.getKey() + " LIKE '%" +
filter.getValue().toString() + "%'");
filterBuild.append(filter.getValue().toString().chars()
.allMatch(Character::isDigit) ? ") ": "");
filterBuild.append(!filters.values().toArray()[filters.size() - 1]
.equals(filter.getValue()) ? " AND " : "");
}
return filterBuild.toString();
}