我按照帖子How to select multiple rows of <h:dataTable> with <h:selectBooleanCheckbox>和Using <h:selectBooleanCheckbox> with Map in a paginated <p:dataTable> throws NullPointerException按照说明进行操作 关于如何从数据表中删除多行。但是,未使用所选值填充选中的Map对象。当我调试应用程序时,它总是空的。
这是我的代码: applicantSearch.xhtml
<ui:composition template="/WEB-INF/templates/main.xhtml">
<ui:define name="menu">
<ui:include src="/protected/views/menu.xhtml"/>
</ui:define>
<ui:define name="content">
<h:outputScript target="body">
formatMyTable();
</h:outputScript>
<h3>Search for Applicants</h3>
<h:form id="searchForm" class="form-search">
<h:panelGroup id="results" class="table-responsive">
<h:outputText id="informationMessage"
value="#{applicantSearchBacking.infoMessage}"
rendered="#{applicantSearchBacking.infoMessage ne null}"
class="informationMessage"/>
<div class="btn-toolbar">
<h:commandButton value="Delete Selected" onclick="if (! confirm('Are you sure you want to delete the selected applicants?')) return false" action="#{applicantSearchBacking.removeSelectedApplicants}" class="btn btn-danger btn-large pull-right">
<f:ajax render=":searchForm:results :searchForm:messages" onevent="formatMyTable"
/>
</h:commandButton>
</div>
<br/>
<h:dataTable value="#{applicantSearchBacking.applicantList}"
var="currentApplicant" styleClass="table table-hover table-condensed table-bordered"
>
<h:column>
<f:facet name="header">
Applicant ID
</f:facet>
#{currentApplicant.applicantId}
</h:column>
<h:column>
<f:facet name="header">
First Name
</f:facet>
#{currentApplicant.firstName}
</h:column>
<h:column>
<f:facet name="header">
Middle Name
</f:facet>
#{currentApplicant.middleName}
</h:column>
<h:column>
<f:facet name="header">
Last Name
</f:facet>
#{currentApplicant.lastName}
</h:column>
<h:column>
<f:facet name="header">
Actions
</f:facet>
<!-- User Access control section <c:if test=""> -->
<h:link value="Edit" outcome="#{applicantSearchBacking.editApplicant()}" class="btn btn-primary btn-sm">
<f:param name="myApplicantId" value="#{currentApplicant.applicantId}">
</f:param>
</h:link>
<!-- </c:if> -->
<!-- <c:if test=""> -->
<h:selectBooleanCheckbox id="del_checkbox" value="#{applicantSearchBacking.checked[currentApplicant.applicantId]}">
</h:selectBooleanCheckbox>
<!-- </c:if> -->
</h:column>
</h:dataTable>
</h:panelGroup>
<h:messages id="messages" class="errorMessage"/>
</h:form>
</ui:define>
applicantSearchBacking.java
private Map<Integer, Boolean> checked = new HashMap<>();
public void removeSelectedApplicants()
{
try {
List<Applicant> applicantsToDelete = new ArrayList<>();
for (Applicant applicant : applicantList) {
Boolean itemChecked = checked.get((applicant.getApplicantId()));
if (itemChecked !=null && itemChecked) {
applicantsToDelete.add(applicant);
}
}
applicantManager.removeSelectedApplicants(applicantsToDelete);
if (!checked.isEmpty())
infoMessage = "Applicant(s) deleted successfully";
checked.clear();
}
答案 0 :(得分:1)
只有在为回发保留完全相同的数据模型时,此构造才有效。因此,如果您的bean是@RequestScoped
,那么它必须在applicantList
内创建与显示表单时完全相同的@PostConstruct
。否则,您需要创建bean @ViewScoped
。无论如何,我假设applicantList
的getter方法没有做任何业务逻辑,只是单独返回属性。
根据您的问题更新,还有另一个可能导致此构造失败的潜在错误:
<f:ajax render=":searchForm:results :searchForm:messages" onevent="formatMyTable" />
此处execute
的{{1}}未指定,因此默认使用<f:ajax>
。您需要显式指定@this
才能在提交时处理整个表单,否则只会处理父组件(命令按钮本身)。
@form