【问题标题】:Primefaces confirmation dialolog in tab view does not hide after action is fired触发操作后,选项卡视图中的 Primefaces 确认对话框不会隐藏
【发布时间】:2012-11-23 14:49:34
【问题描述】:

我的确认对话框有问题。单击确认按钮后它不会关闭。仅当我的表单位于选项卡视图中时才会发生这种情况。 (如果我的表单不在选项卡视图中,而只是在面板或类似的东西中,那么某些代码可以正常工作。)

        <h:form id="timingTableForm">
            <p:dataTable var="item" value="#{requestBean.rmRequest.timingList}" id="timingDataTable" editable="true">
             // some dataTable 
            </p:dataTable>
            <p:confirmDialog closable="true" appendToBody="true" id="confirmDialog" message="#{msg.conf_deleteyesno}" header="#{msg.conf_header}" severity="alert" widgetVar="confirmation">  
                <p:commandButton id="confirm" value="#{msg.btn_yessure}" update="timingTableForm" oncomplete="confirmation.hide()" actionListener="#{requestBean.deleteTiming}" process="@this"/>  
                <p:commandButton id="decline" value="#{msg.btn_notyet}" onclick="confirmation.hide()" type="button" />   
            </p:confirmDialog>
        </h:form>

如果我将“oncomplete”更改为“onclick”,它也可以正常工作,但我希望对话框在服务器端操作完成之前消失。

当我按下确认按钮时,生成的 HTML 中发生了一些奇怪的事情:

<div id="mainTabView:timingTableForm:confirmDialog" class="ui-confirm-dialog ui-dialog ui-widget ui-widget-content ui-overlay-hidden ui-corner-all ui-shadow" style="width: auto; height: auto;">

<div id="mainTabView:timingTableForm:confirmDialog" class="ui-confirm-dialog ui-dialog ui-widget ui-widget-content ui-corner-all ui-shadow ui-overlay-visible" style="width: auto; height: auto; left: 994.5px; top: 186px; visibility: visible; z-index: 1006;">

呈现了一个与我的确认对话框具有相同 ID 的新 div。结果是一个隐藏的确认对话框(如预期的那样),但还有一个仍然可见的新对话框。 如果我再次按下确认按钮,我将有 2 个隐藏的符合对话框和 1 个可见的对话框,依此类推...

我做错了吗?你能发现任何错误吗?或者这可能是 primefaces 中的错误?

  • Primefaces 3.4.1
  • 在 GlassFish 3.1.2 上运行
  • 浏览器 Firefox 16.0.2

提前谢谢你, 范儿


其实我找到了解决问题的方法:

只有在我尝试更新包含确认对话框的整个表单时才会出现问题。如果我只更新此表单中的某些特定区域,它可以正常工作。

【问题讨论】:

  • 为什么不把你的confirmDialog移到tabView之外呢?
  • 由于某些模板设计,此处无法执行此操作,但无论如何感谢您的评论。我最终在这里找到了解决我的问题的方法。我不允许更新整个表单,但如果我更新此表单中的每个子项(对话框除外),一切正常

标签: jsf jsf-2 primefaces


【解决方案1】:

对话框不应放置在任何表单内,而应放置在任何表单外并拥有自己的表单。

<h:form id="timingTableForm">
    <p:dataTable var="item" value="#{requestBean.rmRequest.timingList}" id="timingDataTable" editable="true">
     // some dataTable 
    </p:dataTable>
</h:form>

<p:confirmDialog closable="true" appendToBody="true" id="confirmDialog" message="#{msg.conf_deleteyesno}" header="#{msg.conf_header}" severity="alert" widgetVar="confirmation">  
    <h:form>
        <p:commandButton id="confirm" value="#{msg.btn_yessure}" update="timingTableForm" oncomplete="confirmation.hide()" actionListener="#{requestBean.deleteTiming}" process="@this"/>  
        <p:commandButton id="decline" value="#{msg.btn_notyet}" onclick="confirmation.hide()" type="button" />   
    </h:form>
</p:confirmDialog>

这是因为对话框的 HTML 表示可能在真正的 HTML DOM 树中被移动到当前表单之外(正如您在 appendToBody="true" 明确所做的那样),这可能会在异步请求和更新期间导致“wtf”行为,因为您正在经历。

【讨论】:

  • 你是对的,它在生成的 HTML 中的当前表单之外,但我没想到这可能是一个问题,因为正确的表单是由生成的 JavaScript 提交的。我将这个对话框放入第一个表单的原因是,我必须从这个表单中提交一些额外的数据。但我可以用一些隐藏输入字段来处理这个问题。谢谢你,范特
  • 或者只使用视图范围的bean。无论如何,同一视图中的多个表单将引用同一视图范围的 bean 实例。
  • 是的,但这不是重点。问题是,这个数据没有提交,我按下确认按钮。因此,如果我将使用两个表单,要么我必须提交第一个表单(通过一些 JS),要么我必须将此数据放入第二个表单(用于确认对话框),不是吗?
  • 只需在调用该操作时设置数据,该操作应打开确认对话框并(如有必要)在确认对话框中调用取消时清除数据。
猜你喜欢
  • 2014-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多