JSF 在一个数据表中显示两个列表
JSF Display two lists in one datatable
所以我有 2 个列表,其中一个来自数据库,第二个列表稍后用传递的名称更新。当用户显示页面时,第一个列表是在@PostConstruct 方法上获取的,第二个列表是为 etiquette
.
中的每个 name
值更新的
showClients.java
具有 @ViewScoped 值的 bean
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;
}
目前一切正常。我 etiquetteList
和 clientList
都装满了数据。自从我开始使用这些数据进行调试以来,我就这样做了
<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
中显示它 - 我想要可切换的功能(可切换的方式是您只需单击礼仪名称和 show/hide 客户信息) ,分页,延迟获取等。据我尝试实现,我已经做到了。
<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>
这就是我想要显示数据的方式。我该如何处理?我读到你不能设置 table 的 header,因为 table 是逐行生成的,数据还没有显示为 header。有什么解决方法吗?另外,如何使我的 table 行(这一行带有 e.name
)可以切换?在dataTable
里面用一些panelGrid
?
+----------------------------------------------------+
| e.name (value) |
+-----------------------------------------------------
| Email (string) | Detail (string) | Delete (string) |
| c.email | button | button |
<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>
我已经发布了答案,但在与@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
元素并将其替换为 <p:panel>
这样您可以更轻松地设置面板的 header 也将是 toggleable
.在 facet
元素中,我设置了通用名称 table - 它是 header。接下来我们有另一个 <p:panel>
- 我们有 2 个面板的原因是您可以先打开,然后再打开包含客户列表的第二个。所以现在我们有嵌套数据table。 <p:dataTable>
table 都用于从列表中获取数据。使用分页和滚动等非常容易,您只需将新参数添加到 dataTable 属性即可。每个 dataTable
都必须有 <p:column>
来显示数据,所以我们用它来包装 <p:panelGrid>
我们的页面布局。就 <p:ajax>
而言。每当我们切换第一个面板时,我们都用它来显示一些弹出消息。在您的 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);
}
所以我有 2 个列表,其中一个来自数据库,第二个列表稍后用传递的名称更新。当用户显示页面时,第一个列表是在@PostConstruct 方法上获取的,第二个列表是为 etiquette
.
name
值更新的
showClients.java
具有 @ViewScoped 值的 bean
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;
}
目前一切正常。我 etiquetteList
和 clientList
都装满了数据。自从我开始使用这些数据进行调试以来,我就这样做了
<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
中显示它 - 我想要可切换的功能(可切换的方式是您只需单击礼仪名称和 show/hide 客户信息) ,分页,延迟获取等。据我尝试实现,我已经做到了。
<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>
这就是我想要显示数据的方式。我该如何处理?我读到你不能设置 table 的 header,因为 table 是逐行生成的,数据还没有显示为 header。有什么解决方法吗?另外,如何使我的 table 行(这一行带有 e.name
)可以切换?在dataTable
里面用一些panelGrid
?
+----------------------------------------------------+
| e.name (value) |
+-----------------------------------------------------
| Email (string) | Detail (string) | Delete (string) |
| c.email | button | button |
<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>
我已经发布了答案,但在与@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
元素并将其替换为 <p:panel>
这样您可以更轻松地设置面板的 header 也将是 toggleable
.在 facet
元素中,我设置了通用名称 table - 它是 header。接下来我们有另一个 <p:panel>
- 我们有 2 个面板的原因是您可以先打开,然后再打开包含客户列表的第二个。所以现在我们有嵌套数据table。 <p:dataTable>
table 都用于从列表中获取数据。使用分页和滚动等非常容易,您只需将新参数添加到 dataTable 属性即可。每个 dataTable
都必须有 <p:column>
来显示数据,所以我们用它来包装 <p:panelGrid>
我们的页面布局。就 <p:ajax>
而言。每当我们切换第一个面板时,我们都用它来显示一些弹出消息。在您的 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);
}