【问题标题】:Using h:selectBooleanCheckbox to delete multiple rows in JSF datatable使用 h:selectBooleanCheckbox 删除 JSF 数据表中的多行
【发布时间】:2014-10-14 08:58:28
【问题描述】:

我已按照帖子 How to select multiple rows of <h:dataTable> with <h:selectBooleanCheckbox>Using <h:selectBooleanCheckbox> with Map in a paginated <p:dataTable> throws NullPointerException 的说明进行操作 关于如何从数据表中删除多行。但是,选中的 Map 对象没有填充选定的值。当我调试应用程序时,它总是空的。

这是我的代码: 申请人搜索.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();

}

【问题讨论】:

    标签: jsf jsf-2 datatable


    【解决方案1】:

    仅当为回发保留完全相同的数据模型时,此构造才会起作用。因此,如果您的 bean 是 @RequestScoped,那么它必须在 @PostConstruct 内创建与显示表单时完全相同的 applicantList。否则,您需要制作 bean @ViewScoped。无论如何,我假设applicantList 的getter 方法不做任何业务逻辑,而只是返回属性。

    另见:


    根据您的问题更新,还有另一个可能导致此构造失败的潜在错误:

    <f:ajax render=":searchForm:results :searchForm:messages" onevent="formatMyTable" />
    

    &lt;f:ajax&gt;execute 在此处未指定,因此使用默认值 @this。您需要明确指定@form 以便在提交时处理整个表单,否则只会处理父组件(命令按钮本身)。

    <f:ajax execute="@form" ... />
    

    【讨论】:

    • applicant List 真的不做任何业务逻辑,它只返回你所说的属性。我正在使用@ViewScoped,而我的applicantList 正在@PostConstruct 中生成。
    • 好吧,那么问题的实际原因超出了问题中迄今为止提供的信息。为了排除第一个下一个可能的嫌疑人:您究竟是如何提交表单的?
    • 我已经编辑了帖子以包含整个 applicantSearch.xhtml 页面,以便您可以看到我是如何提交表单的。
    • 印象派!问题解决了。非常感谢 BalusC,现在我看到了清楚地陈述问题的重要性。
    • 不客气。很高兴你看到它的重要性。这也很有帮助:stackoverflow.com/help/mcve
    猜你喜欢
    • 2012-07-11
    • 1970-01-01
    • 2011-04-30
    • 1970-01-01
    • 2013-11-07
    • 2018-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多