除了在对话框上显示动态消息外,还阻止p:confirmDialog上显示的p:commandButton

时间:2014-07-31 21:33:37

标签: jsf primefaces jsf-2.2

我正在尝试阻止<p:commandButton>上显示的<p:confirmDialog>,如下所示。

<p:confirmDialog id="confirmDeleteDialog" widgetVar="confirmDelete" message="Message" closeOnEscape="true" appendTo="@(body)" closable="true">
    <p:blockUI block="confirm" widgetVar="blockUI">
        <h:outputText value="Demo"/>
    </p:blockUI>

    <p:commandButton id="confirm" value="Yes" onstart="PF('blockUI').show()" oncomplete="PF('blockUI').hide();"/> <!--Use PF('confirmDelete').hide() to dismiss the dialog.-->
    <p:commandButton id="decline" value="No" onclick="PF('confirmDelete').hide()" type="button" />               
</p:confirmDialog>

<p:commandButton oncomplete="PF('confirmDelete').show()"/>

这会阻止id="confirm"保留按钮(<p:confirmDialog>)按钮。

要在确认对话框中显示的消息是动态的。它是根据某些条件从关联的辅助bean中获取的。因此,对话框在显示之前需要更新。

要在显示对话框之前更新对话框,<p:commandButton>的更新属性设置如下。

<p:commandButton oncomplete="PF('confirmDelete').show()" update="confirmDeleteDialog"/>

这当然会动态地在对话框上显示所需的消息(为简单起见,此处未对此进行演示)但这样做会阻止<p:blockUI>运行 - 它不会阻止<p:commandButton> ,如果对话框由它更新。

浏览器控制台上的错误和服务器终端上的异常都没有出现。

除了在对话框上显示动态消息外,阻止a所持按钮的方式是什么?


编辑: - 我提供的答案是交叉标记。

正如我在给出的答案中所指出的,<p/pe:blockUI>需要更新,当点击确认对话框所持有的<p:commandButton>时,需要一些时间来阻止按钮 - {{1}点击后点击。同时,在初始请求完成之前,可以单击(有意或无意地)按钮,这可能会导致重复提交,这肯定会违反使用<p:commandButton>

<p/pe:blockUI>阻止按钮之前,没有任何东西阻止用户在我的解决方法中多次点击该按钮。因此,我提供的答案被认为是交叉标记。

或许满足这一要求的方式完全不同。


编辑2: - 实际情况。

<p/pe:blockUI>

消息框在这里:

//A view scoped bean.
//A list of selected rows in <p:dataTable>.
private List<WishUtils>selectedValues;
//The actual message to be displayed on the dialog.
private String deleteMsg;
//Associated with the rendered property of the "Yes" button on the dialog.
private boolean renderedYesButtonDelete=true;
//The header message/text of the dialog.
private String messageBoxHeader;
//The no button text (its value).
private String noButtonTextDelete="No";

//Getters and setters as required.

public void confirmDelete(ActionEvent actionEvent) {
    if(selectedValues!=null && !selectedValues.isEmpty()) {
        renderedYesButtonDelete=true;
        noButtonTextDelete="No";
        deleteMsg="A long message about a delete prompt from a resource bundle";
        messageBoxHeader="Confirm Delete";
    } else {
        noButtonTextDelete="OK";
        renderedYesButtonDelete=false;
        deleteMsg="Please select the rows you want to delete";
        messageBoxHeader="Confirm Item Select";
    }
}

public void delete(ActionEvent actionEvent) {
    if(actionEvent.getComponent().getId().equals("confirmDeleteMultiple")) {
        //Delete the selected rows.
    } else {
        //Notify an error (generally never going to be executed).
    }
}

2 个答案:

答案 0 :(得分:3)

整个对话框更新后,<p:blockUI>确实失败了。看起来只是另一个bug。当您在对话框更新完成时显式调用PrimeFaces.cw(...)组件的<p:blockUI>“创建窗口小部件”脚本(完全是在<p:blockUI>生成的HTML输出表示中看到的脚本)时,它可以正常工作。

鉴于这些ID,

<h:form id="formId">
    <p:confirmDialog id="confirmDialogId">
        <p:blockUI id="blockId" ... />
        <p:commandButton id="confirmButtonId" ... />

以下oncomplete应该这样做:

<p:commandButton update="confirmDialogId" 
    oncomplete="PrimeFaces.cw('BlockUI','blockUI',{id:'formId:blockId',block:'formId:confirmId'});PF('confirmDialogId').show()" />

这就解释了为什么<p:remoteCommand>技巧的作用,因为它在封面下基本上会重新生成<p:blockUI>组件以及PrimeFaces.cw(...)调用,尽管它会触发不必要的ajax请求。可能值得向PrimeFaces人员报告一个问题,告知更新确认对话框小部件时PrimeFaces.cw(...)的{​​{1}}未正确执行。

另一种解决方法是明确地ajax更新您想要更新的部分而不是整个对话框。这对我行得通。 <p:blockUI>的{​​{1}}和header属性(以及许多其他PrimeFaces组件的属性)支持通过message在属性名称上定义。这允许您将其包装在<p:confirmDialog>(或<f:facet>)中,以便您可以单独更新它。这样您就不需要更新整个对话框,并且块UI保持按预期工作。

<h:outputText>

答案 1 :(得分:1)

当点击确认对话框中显示的<p/pe:blockUI>时,这需要更新<p:commandButton>

<p:blockUI>可以使用onclick更新<p:remoteCommand>onstart也有效)。

代码就在这里。

<p:confirmDialog id="confirmDeleteDialog" widgetVar="confirmDelete" message="Message" closeOnEscape="true" appendTo="@(body)" closable="true">
    <p:blockUI id="blockConfirm" block="confirm" widgetVar="blockUI"/>
    <p:remoteCommand name="confirmCommand" update="blockConfirm"/>

    <!--Add PF('confirmDelete').hide() to oncomplete to dismiss the dialog, when this button is clicked.-->
    <p:commandButton id="confirm" value="Yes" onclick="confirmCommand();" onstart="PF('blockUI').show()" oncomplete="PF('blockUI').hide()"/>
    <p:commandButton id="decline" value="No" onclick="PF('confirmDelete').hide()" type="button" />                
</p:confirmDialog>

<p:commandButton oncomplete="PF('confirmDelete').show()" update="confirmDeleteDialog" value="Submit"/>