【问题标题】:JSF Display two lists in one datatableJSF 在一个数据表中显示两个列表
【发布时间】:2020-05-12 12:52:37
【问题描述】:

所以我有 2 个列表,其中一个来自数据库,第二个稍后用传递的名称更新。第一个列表在用户显示页面时通过@PostConstruct 方法获取,第二个列表针对来自etiquette 的每个name 值进行更新。

showClients.java bean 与 @ViewScoped 值

     private List<Etiquette> etiquetteList;
     private List<Client> clientList;

    ...getters and setters 

       @PostConstruct
        public void init() {
            HttpSession session = SessionUtil.getSession();
            User user = (User) session.getAttribute("user");
            etiquetteList = etiquetteDAO.getAllEtiquettes(user);
            System.out.println(etiquetteList);
        }

        public List<Client> showClientsForEtiquette(String etiquetteName) {
            clientList = clientDAO.findClientsByEtiquetteName(etiquetteName);
            System.out.println(clientList);
            return clientList;
        }

目前一切正常。我已经etiquetteListclientList 充满了数据。自从我开始使用这些数据进行调试以来,我已经这样做了

<h:form>
    <ui:repeat value="#{showClients.etiquetteList}" var="etiquette">
                        <p:panel id="horizontal" header="#{etiquette.name}" toggleSpeed="100" toggleable="true" toggleOrientation="vertical" collapsed="true" >  
                            <p:panelGrid columns="3" layout="grid" styleClass="showcase-text-align-center" >
                                <h:outputText value="Client name"/>
                                <h:outputText value="Client email"/>
                                <h:outputText value="Show details"/>
                            </p:panelGrid>
                            <p:panelGrid id="clientData" styleClass="showcase-text-align-center">
                                <ui:repeat value="#{showClients.clientList}" var="client">
                                    <p:panelGrid columns="3" layout="grid" styleClass="showcase-text-align-center" >
                                        <h:outputText value="#{client.name}"/>
                                        <h:outputText value="#{client.email}"/>
                                        <p:commandButton value="details" type="button" onclick="PF('clientDetails').show();" >
                                            <f:param name="client" value="client"/>
                                        </p:commandButton>
                                    </p:panelGrid>
                                </ui:repeat>
                            </p:panelGrid>
                        </p:panel>   
                    </ui:repeat>
    </h:form>

但是这种方式很笨拙,我想以非常不同的方式显示这些数据。我想使用PrimeFaces 库在dataTable 中显示它 - 我想要可切换的功能(可切换方式,您只需单击礼仪名称并显示/隐藏客户信息)、分页、延迟获取等. 就我所尝试的实现而言,我已经做到了。

        <h:form id="groupForm">
                        <h:form>
                        <p:dataTable value="#{showClients.etiquetteList}" var="e" sortBy="#{e.name}" expandedRow="false"  expandableRowGroups="true"  rows="10"
                                     paginator="true"
                                     paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
                                     currentPageReportTemplate="{startRecord}-{endRecord} of {totalRecords} records"
                                     rowsPerPageTemplate="5,10,15" >
                            <p:headerRow>
                                <f:facet name="header">
                                <p:column colspan="3">
                                    <h:outputLabel value="#{e.name}" />
                                </p:column>
                                </f:facet>
                            </p:headerRow>
                            <p:column colspan="3" style="margin: 20px 0;" >
                                <p:dataTable value="#{showClients.showClientsForEtiquette(e.name)}" var="c" lazy="true" expandedRow="false">
                                    <p:column headerText="Email">
                                        #{c.email}
                                    </p:column>
                                    <p:column headerText="Szczegóły">
                                        <p:commandButton value="Szczegóły"/>
                                    </p:column>
                                    <p:column  headerText="Usuń" >
                                        <p:commandButton value="Usuń"/>
                                    </p:column>
                                </p:dataTable>
                            </p:column>

                        </p:dataTable>
                    </h:form>

这就是我想要显示我的数据的方式。我该如何处理?我已经读到您无法设置表头,因为表是逐行生成的,并且数据还没有显示为表头。有什么解决方法吗?另外,如何使我的表格行(此行带有 e.name )可切换?在dataTable 中使用一些panelGrid

+----------------------------------------------------+
|                      e.name (value)                | 
+-----------------------------------------------------
| Email (string) | Detail (string) | Delete (string) |
|     c.email    |      button     |     button      |

【问题讨论】:

  • 使用 PrimeFaces 'p:overlay'?
  • 但是我想不断地在我的应用程序的子页面上显示该表格,并使用 p:overlay 作为客户端的详细信息值,那不是问题吗?
  • 如果你想使用子页面然后使用子页面......这都是简单的主从功能。但在我看来,这个标题完全不相关......见stackoverflow.com/questions/8459903/…。请澄清您的问题
  • 但是我的问题是相关的...我想循环遍历 2 个列表并以某种指定的方式将数据显示为 dataTable 给用户,但我不知道如何实现我指定的
  • 那么我的评论是:“如果你使用纯 java 和System.out.println 来显示,你会怎么做,你必须改变模型服务器端。在这里做同样的事情...

标签: jsf


【解决方案1】:

我已经发布了答案,但在与@Kukeltje 的评论部分讨论后,我决定改变一些事情。所以这里有一个代码。

<h:form id="groupsForm">
            <p:dataTable value="#{showClients.etiquetteList}" 
                         var="e" 
                         style="width: 80%; margin:0 auto;" 
                         paginator="true" 
                         rows="5" 
                         rowsPerPageTemplate="5,10,15,20,50" 
                         lazy="true" 
                         paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
                         currentPageReportTemplate="{startRecord}-{endRecord} of {totalRecords} records">
                <p:column>
                    <p:growl id="msgs" showDetail="true" skipDetailIfEqualsSummary="true" />
                    <f:facet name="header">General header</f:facet>                    
                    <p:panel id="toggleable" header="#{e.name}" toggleable="true" toggleSpeed="500" collapsed="true" style="margin: 5px 0; border: 0;">
                        <p:ajax event="toggle" listener="#{showClients.onToggle}" update="msgs"/>
                        <p:panel toggleable="true" header="Client" toggleSpeed="500" collapsed="true" style="margin: 5px 0; border: 0;">                            
                            <p:dataTable value="#{e.clientCollection}" 
                                         var="c" 
                                         lazy="true" 
                                         paginator="true" 
                                         rows="5" 
                                         rowsPerPageTemplate="5,10,15,20,50"                                         
                                         paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
                                         currentPageReportTemplate="{startRecord}-{endRecord} of {totalRecords} records"
                                         reflow="true"
                                         >
                                <p:column>
                                    <p:panelGrid columns="4" style="margin: 5px 0; border: 0;">   
                                        <p:column headerText="Name" priority="1">
                                            #{c.name}
                                        </p:column>
                                        <p:column headerText="Email" priority="1">
                                            #{c.email}
                                        </p:column>
                                        <p:column headerText="Email" priority="2">
                                            <p:commandButton value="Details"/>
                                        </p:column>
                                        <p:column headerText="Email" priority="3">
                                            <p:commandButton value="Delete"/>
                                        </p:column>
                                    </p:panelGrid>
                                </p:column>
                            </p:dataTable>
                        </p:panel>
                    </p:panel>
                </p:column>
            </p:dataTable>
        </h:form>

我正在使用PrimeFaces library。那么与您的代码相比有什么变化。起初,我去掉了headerRow 元素并将其替换为&lt;p:panel&gt;,这样您就可以更轻松地设置面板的标题,也就是toggleable。在facet 元素中,我设置了表的通用名称 - 它是标题。接下来我们有另一个&lt;p:panel&gt; - 我们有两个面板的原因是您可以先打开,然后再打开第二个包含客户列表的面板。所以现在我们有嵌套的数据表。 &lt;p:dataTable&gt; 两个表都用于从列表中获取数据。使用分页和滚动等非常容易,您只需向 dataTable 属性添加新参数即可。每个dataTable 都必须有&lt;p:column&gt; 来显示数据,所以我们用它来包装&lt;p:panelGrid&gt; 与我们的页面布局。至于&lt;p:ajax&gt;。每当我们切换第一个面板时,我们都会使用它来显示一些弹出消息。在你的bean中,你应该有一个使用FacesMessage更新值的方法,甚至作为参数传递给ajax。
showClients.java toggle method

    public void onToggle(ToggleEvent event) {
        FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, event.getComponent().getId() + " toggled", "Status:" + event.getVisibility().name());
        FacesContext.getCurrentInstance().addMessage("groupsForm:msgs", message);
    }

【讨论】:

  • 对最终用户来说不是双重可切换混淆吗?就我个人而言,我会使用行扩展并添加一些小的一行 javascript,然后单击行中的任意位置展开数据表
  • 我认为当您从第二个面板中删除 collapsed="true" 时,双重切换不会令人困惑,然后当您切换第一个面板时,您会立即加载客户端......我正在学习这些东西,这就是我想到实施的第二个想法:)
  • 这就是我想要的。 @Kukeltje 你建议使用一些 JS 来切换第二个面板?我认为他有点过度使用可切换,我想我会摆脱它,只显示为启用分页的常规面板。
【解决方案2】:
<h:form id="groupsForm">

            <p:dataTable value="#{showClients.etiquetteList}" var="e">
                <p:column>
                    <f:facet name="header">Some header</f:facet>
    <p:growl id="msgs" showDetail="true" skipDetailIfEqualsSummary="true" />
                    <p:panel id="toggleable" header="#{e.name}" toggleable="true" toggleSpeed="500" style="margin: 20px 0;">
                        <p:ajax event="close" listener="#{showClients.onClose}" update="msgs"/>
                        <p:ajax event="toggle" listener="#{showClients.onToggle}" update="msgs"/>
                        <p:repeat value="#{e.clientCollection}" var="c" >
                            <p:panelGrid columns="3" >
                                <p:column headerText="Email">
                                    #{c.email}
                                </p:column>
                                <p:column headerText="Detail">
                                    <p:commandButton value="Detail"/>
                                </p:column>
                                <p:column headerText="Delete">
                                    <p:commandButton value="Delete"/>
                                </p:column>
                            </p:panelGrid>
                        </p:repeat>
                    </p:panel>

                </p:column>
            </p:dataTable>
        </h:form>

【讨论】:

  • 你为什么给我负数?在我的屏幕上,它看起来像是他想要实现的目标
  • 有一条评论,但它要么被删除,要么我忘记按提交。这是因为缺乏关于添加/更改内容的文本上下文/解释以及添加一些关于限制的文本(OP 必须添加 css 以可能以某种不会在视觉上变得拥挤的方式隐藏面板)。实际上只有代码......干杯......哦,数据表内的咆哮会导致奇怪的行为
  • 抱歉,缺少评论!
  • 可切换面板的基本方法确实可以工作,但我不明白为什么你需要 ajax 并更新消息和切换,默认情况下仅适用于打开/关闭图标(也许不是为什么 OP想要)并且确实OP错过了一些关于“孩子/细节/客户”数量以及真实行为的细节(在某种程度上让我感到困惑)。 Rowexpansion 也可能是一个解决方案......
  • 这就是为什么你应该给它发文字解释 ;-) 请这样做,然后我可以删除反对票(我想 ;-))
猜你喜欢
  • 1970-01-01
  • 2019-12-07
  • 1970-01-01
  • 2018-08-26
  • 1970-01-01
  • 1970-01-01
  • 2016-06-06
  • 2014-05-27
  • 2011-02-03
相关资源
最近更新 更多