PrimeFaces数据表:如何接收选定的行值?

时间:2018-08-02 13:46:10

标签: primefaces jsf-2

已编辑:没有完整的信息。

我使用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"属性,但似乎它们执行不同的操作。

那么,您能否举例说明如何从事件对象中检索此类数据?我应该使用另一种方法来解决吗?感谢您的提前答复。

2 个答案:

答案 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,这并不会停留在页面更改上。

  1. 您需要使用集合类型设置selection参数

  2. getRowKey内插入LazyDataModel并删除rowKey="#{ticket.id}"

  3. 带有复选框的选择不需要selectionMode="multiple"

    • 仅在按下CTRL键的情况下单击表格行时,此参数才可进行多个选择
  4. 我的建议是手动控制您选择的数据

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