带子表和多项选择的 Primefaces 数据表

发布于 2025-01-06 14:55:58 字数 2225 浏览 0 评论 0原文

我想要一张按客户分组的预订表。从该表中,用户应能够选择多个预订进行计费。所以我尝试使用子表进行分组,但是,我不确定如何实现选择功能。显然子表不允许选择属性,如果我在父数据表上设置选择属性,我不知道如何选择 rowKey。

这是我的尝试:

<p:dataTable style="border: 0px;" value='#{clientController.allClients}'
             var='client' rowKey="#{item.id}"  selectionMode="multiple"
             selection="#{bookingController.bookingsToBill}">
  <p:subTable value='#{client.billableBookings}' var='item'>
    <f:facet name="header"> 
        <h:outputText style="font-weight:bold;" value="#{client.name}" />
    </f:facet>
    <p:column>
        <f:facet name="header">
            <h:outputText value="Booking"/>
        </f:facet>
        <h:outputText value="#{item.title}"/>
    </p:column>
  </p:subTable>
</p:dataTable>

嗯,这会在提交选择时导致以下错误:

java.lang.NullPointerException
   java.lang.reflect.Array.newArray(Native Method)
   java.lang.reflect.Array.newInstance(Array.java:52)
   org.primefaces.component.datatable.DataHelper.decodeMultipleSelection(DataHelper.java:238)
   org.primefaces.component.datatable.DataHelper.decodeSelection(DataHelper.java:224)
   org.primefaces.component.datatable.DataTableRenderer.decode(DataTableRenderer.java:64)
   javax.faces.component.UIComponentBase.decode(UIComponentBase.java:787)
   javax.faces.component.UIData.processDecodes(UIData.java:1162)
   org.primefaces.component.datatable.DataTable.processDecodes(DataTable.java:531)
   javax.faces.component.UIForm.processDecodes(UIForm.java:225)
   javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1176)
   javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1176)
   javax.faces.component.UIViewRoot.processDecodes(UIViewRoot.java:933)
   com.sun.faces.lifecycle.ApplyRequestValuesPhase.execute(ApplyRequestValuesPhase.java:78)
   com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
   com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
   javax.faces.webapp.FacesServlet.service(FacesServlet.java:409)

带有子表的数据表是否支持多重选择?如果是这样,该怎么做才正确呢?如果没有,您建议采用哪种方法来达到类似的结果?

我正在使用:Primefaces 3.1.1 - Mojarra JSF 2.1 - Tomcat 6.0.14

I would like to have a table of bookings grouped by clients. From this table the user shall be able to select multiple booking for billing. So I am trying to use a SubTable for the grouping, however, I am unsure how to realize to selection functionality. Apparently the subtable doesn't allow the selection attribute and if I set the selection attribute on the parent DataTable I don't know how to choose the rowKey.

That is my try:

<p:dataTable style="border: 0px;" value='#{clientController.allClients}'
             var='client' rowKey="#{item.id}"  selectionMode="multiple"
             selection="#{bookingController.bookingsToBill}">
  <p:subTable value='#{client.billableBookings}' var='item'>
    <f:facet name="header"> 
        <h:outputText style="font-weight:bold;" value="#{client.name}" />
    </f:facet>
    <p:column>
        <f:facet name="header">
            <h:outputText value="Booking"/>
        </f:facet>
        <h:outputText value="#{item.title}"/>
    </p:column>
  </p:subTable>
</p:dataTable>

Well, this results in the following error when submitting the selection:

java.lang.NullPointerException
   java.lang.reflect.Array.newArray(Native Method)
   java.lang.reflect.Array.newInstance(Array.java:52)
   org.primefaces.component.datatable.DataHelper.decodeMultipleSelection(DataHelper.java:238)
   org.primefaces.component.datatable.DataHelper.decodeSelection(DataHelper.java:224)
   org.primefaces.component.datatable.DataTableRenderer.decode(DataTableRenderer.java:64)
   javax.faces.component.UIComponentBase.decode(UIComponentBase.java:787)
   javax.faces.component.UIData.processDecodes(UIData.java:1162)
   org.primefaces.component.datatable.DataTable.processDecodes(DataTable.java:531)
   javax.faces.component.UIForm.processDecodes(UIForm.java:225)
   javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1176)
   javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1176)
   javax.faces.component.UIViewRoot.processDecodes(UIViewRoot.java:933)
   com.sun.faces.lifecycle.ApplyRequestValuesPhase.execute(ApplyRequestValuesPhase.java:78)
   com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
   com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
   javax.faces.webapp.FacesServlet.service(FacesServlet.java:409)

Is multiple selection supported for DataTables with SubTables? If so, how to do it right? If not, which way would you suggest to achieve a similar result?

I'm using: Primefaces 3.1.1 - Mojarra JSF 2.1 - Tomcat 6.0.14

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

李不 2025-01-13 14:55:58

您是否分析过 Primefaces 展示中描述的此解决方案

它基本上可以归结为:

<p:dataTable style="border: 0px;" value='#{clientController.allClients}' 
             var='client' rowKey="#{item.id}" 
             selection="#{bookingController.bookingsToBill}" >
<p:subTable value='#{client.billableBookings}' var='item'>
    <f:facet name="header"> 
        <h:outputText style="font-weight:bold;" value="#{client.name}" />
    </f:facet>
    <p:column selectionMode="multiple" />
    <p:column>
        <f:facet name="header">
            <h:outputText value="Booking"/>
        </f:facet>
        <h:outputText value="#{item.title}"/>
    </p:column>
</p:subTable>

或者尝试使用绑定到 BookingController 的 ajax 事件侦听器:

<p:ajax event="rowSelect" listener="#{bookingController.rowSelected}" />
<p:ajax event="rowUnselect" listener="#{bookingController.rowUnselected}" />

并且您在这两个函数中更新自己的选定项目列表:

List<Booking> selectedBookings = new ArrayList<>();
...
public void rowSelected(SelectEvent event) {
    Booking book = (Booking) event.getObject();
    selectedBookings.add(book);
}

public void rowUnselected(UnselectEvent event) {
    Booking book = (Booking) event.getObject();
    selectedBookings.remove(book);
}

这不是很优雅,但它让我的逻辑在得到这个之后工作晦涩难懂的 NullPointerException。

Have you analyzed this solution described in Primefaces' showcase?

It basically boils down to this:

<p:dataTable style="border: 0px;" value='#{clientController.allClients}' 
             var='client' rowKey="#{item.id}" 
             selection="#{bookingController.bookingsToBill}" >
<p:subTable value='#{client.billableBookings}' var='item'>
    <f:facet name="header"> 
        <h:outputText style="font-weight:bold;" value="#{client.name}" />
    </f:facet>
    <p:column selectionMode="multiple" />
    <p:column>
        <f:facet name="header">
            <h:outputText value="Booking"/>
        </f:facet>
        <h:outputText value="#{item.title}"/>
    </p:column>
</p:subTable>

Or try with the ajax event listener, bound to your BookingController:

<p:ajax event="rowSelect" listener="#{bookingController.rowSelected}" />
<p:ajax event="rowUnselect" listener="#{bookingController.rowUnselected}" />

And you update your own list of selected items in these two functions:

List<Booking> selectedBookings = new ArrayList<>();
...
public void rowSelected(SelectEvent event) {
    Booking book = (Booking) event.getObject();
    selectedBookings.add(book);
}

public void rowUnselected(UnselectEvent event) {
    Booking book = (Booking) event.getObject();
    selectedBookings.remove(book);
}

It's not very elegant, but it brought my logic to work after getting this rather obscure NullPointerException.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文