如何在JSF中进行双击预防 [英] How to do double-click prevention in JSF

查看:59
本文介绍了如何在JSF中进行双击预防的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有一些搜索页面,它们会处理大量数据,并且需要一段时间才能完成.当用户点击搜索按钮时,我们不想让他们第二次提交搜索结果.

We have a few search pages that run against a lot of data and take a while to complete. When a user clicks on the search button, we'd like to not allow them to submit the search result a second time.

在JSF中是否有进行双击"检测/预防的最佳实践?

Is there a best practice for doing "double-click" detection/prevention in JSF?

PrimeFaces组件似乎可以完成我们想要的操作,因为它将在单击搜索按钮到搜索完成之间的一段时间内禁用UI,但是有没有更通用的策略可供我们使用(也许不依赖PrimeFaces的东西)?理想情况下,在搜索完成之前,将禁用或忽略对按钮的任何单击.我们不必禁用整个UI(因为blockUI允许您这样做).

The PrimeFaces component seems like it can do what we want as it will disable the UI for a period of time between when the search button is clicked and when the search completes, but is there a more generic strategy we can use (perhaps something that isnt reliant on PrimeFaces)? Ideally, any click of the button will either be disabled or disregarded until the search completes. We dont necessarily need to disable the entire UI (as blockUI allows you to do).

推荐答案

如果仅使用ajax请求,则可以为此使用JSF JavaScript API的jsf.ajax.addOnEvent处理程序.以下示例适用于type="submit"的所有按钮.

If you're using solely ajax requests, you could use jsf.ajax.addOnEvent handler of the JSF JavaScript API for this. The below example will apply on all buttons of type="submit".

function handleDisableButton(data) {
    if (data.source.type != "submit") {
        return;
    }

    switch (data.status) {
        case "begin":
            data.source.disabled = true;
            break;
        case "complete":
            data.source.disabled = false;
            break;
    }    
}

jsf.ajax.addOnEvent(handleDisableButton);

或者,如果仅在特定按钮上需要此按钮,请使用<f:ajax>onevent属性.

Alternatively, if you need this on specific buttons only, use the onevent attribute of <f:ajax>.

<h:commandButton ...>
    <f:ajax ... onevent="handleDisableButton" />
</h:commandButton>

如果还需要在同步请求上应用此选项,则需要考虑到在onclick期间禁用按钮时,按钮的name=value对将不会作为请求参数发送,因此JSF将无法识别该动作并调用它.因此,您应该仅在浏览器发送POST请求后 禁用它.没有DOM事件处理程序,您需要使用setTimeout() hack,该hack会在单击后约50ms禁用按钮.

If you also need to apply this on synchronous requests, then you need to take into account that when you disable a button during onclick, then the button's name=value pair won't be sent as request parameter and hence JSF won't be able to identify the action and invoke it. You should thus only disable it after the POST request has been sent by the browser. There is no DOM event handler for this, you'd need to use the setTimeout() hack which disables the button ~50ms after click.

<h:commandButton ... onclick="setTimeout('document.getElementById(\'' + this.id + '\').disabled=true;', 50);" />

这只是相当脆弱.对于慢速客户端,这可能太短了.您需要增加超时时间或使用其他解决方案.

This is only rather brittle. It might be too short on slow clients. You'd need to increase the timeout or head to another solution.

也就是说,请记住,这只能防止在通过网页提交时重复提交.这不能防止像URLConnection,Apache HttpClient,Jsoup等编程HTTP客户端进行双重提交.如果要在数据模型中强制唯一性,则不应防止双重提交,而应防止双重插入.在SQL中,可以通过在感兴趣的列上放置UNIQUE约束来轻松实现这一点.

That said, keep in mind that this only prevents double submits when submitting by a web page. This does not prevent double submits by programmatic HTTP clients like URLConnection, Apache HttpClient, Jsoup, etc. If you want to enforce uniqueness in the data model, then you should not be preventing double submits, but preventing double inserts. This can in SQL easily be achieved by putting an UNIQUE constraint on the column(s) of interest.

这篇关于如何在JSF中进行双击预防的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆