32

大量のデータに対して実行され、完了するまでに時間がかかる検索ページがいくつかあります。ユーザーが検索ボタンをクリックしたときに、検索結果を 2 回送信できないようにしたいと考えています。

JSFで「ダブルクリック」の検出/防止を行うためのベストプラクティスはありますか?

PrimeFaces コンポーネントは、検索ボタンがクリックされてから検索が完了するまでの期間、UI を無効にするため、私たちが望むことを実行できるように見えますが、使用できるより一般的な戦略はありますか (おそらくそうではないもの) PrimeFaces に依存している)? 理想的には、検索が完了するまで、ボタンのクリックを無効にするか無視します。必ずしも UI 全体を無効にする必要はありません (blockUI でできるように)。

4

8 に答える 8

41

ajax リクエストのみを使用している場合jsf.ajax.addOnEventは、JSF JavaScript API のハンドラーを使用できます。以下の例は、 のすべてのボタンに適用されます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);

または、特定のボタンのみでこれが必要な場合は、 のonevent属性を使用します<f:ajax>

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

onclickこれを同期リクエストにも適用する必要がある場合は、 の実行中にボタンを無効にすると、ボタンのname=valueペアがリクエスト パラメータとして送信されないため、JSF がアクションを識別できないことを考慮する必要があります。そしてそれを呼び出します。したがって、ブラウザから POST リクエストが送信されたにのみ無効にする必要があります。このための DOM イベント ハンドラーはありませんsetTimeout()。クリックしてから約 50 ミリ秒後にボタンを無効にするハックを使用する必要があります。

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

これはかなり脆いだけです。遅いクライアントでは短すぎるかもしれません。タイムアウトを増やすか、別のソリューションに進む必要があります。

とはいえ、これは Web ページから送信する場合の二重送信を防ぐだけであることに注意してください。これは、Apache HttpClient、Jsoup などのプログラムによる HTTP クライアントによる二重送信を防止しませんURLConnection。データ モデルで一意性を強制したい場合は、二重送信を防止するのではなく、二重挿入を防止する必要があります。UNIQUEこれは、対象の列に制約を設定することにより、SQL で簡単に実現できます。

以下も参照してください。

于 2012-05-25T14:56:18.760 に答える
1

上記の代替手段はどれもうまくいきませんでした(実際にそれぞれを試しました)。ユーザーがログイン ボタンをダブルクリックすると、フォームが常に 2 回送信されました。私は Glassfish 3.1.2 で JSF (Mojarra 2.1.6) を使用しています。

非 AJAX ログイン ページであると考えてください。

だからここに私がそれを解決した方法があります:

  1. ページ ヘッダーまたはフォーム外の任意の場所で送信を制御するグローバル JavaScript 変数を定義します。
var submitting = false;
  1. truesubmit h:formonsubmit イベントが発生したときに設定します。
<h:form onsubmit="submitting = true">
  1. h:commandLink のクリック イベントで var の値を確認します。
<h:commandLink ... onclick="if(submitting){return false}">

これはもう 1 つの単純な代替手段であり、Chrome [バージョン 47.0.2526.106 (64 ビット)]、Mozilla Firefox (37.0.2)、および Internet Explorer 11 でテストされています。

于 2016-05-13T23:36:43.277 に答える
0

非表示と表示で簡単な作業を行い、入力タイプがJqueryを送信する要素でうまく機能します

$(":submit").click(function (event) {
    // add exception to class skipDisable 
    if (!$(this).hasClass("skipDisable")) {
        $(this).hide();
        $(this).after("<input type='submit' value='"+$(this).val()+"' disabled='disabled'/>");
    }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
<form>
    <input type="submit" value="hello">
</form>
于 2016-07-21T05:39:20.660 に答える
0

非常に便利なソリューション jsf-primefaces は、facelets テンプレートとともに使用され、他のページの消費者に広がります

<f:view>
    <Script language="javascript">
        function checkKeyCode(evt)
        {
            var evt = (evt) ? evt : ((event) ? event : null);
            var node = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null);
            if(event.keyCode==116)
            {
                evt.keyCode=0;
                return false
            }
        }
        document.onkeydown=checkKeyCode;

        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);
    </Script>

</f:view>

<h:head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <link href="./resources/css/default.css" rel="stylesheet" type="text/css" />
    <link href="./resources/css/cssLayout.css" rel="stylesheet" type="text/css" />
    <title>infoColegios - Bienvenido al Sistema de Administracion</title>
</h:head>

<h:body onload="#{login.validaDatos(e)}">
    <p:layout fullPage="true">

        <p:layoutUnit position="north" size="120" resizable="false" closable="false" collapsible="false">                   
            <p:graphicImage value="./resources/images/descarga.jpg" title="imagen"/> 
            <h:outputText value="InfoColegios - Bienvenido al Sistema de Administracion" style="font-size: large; color: #045491; font-weight: bold"></h:outputText>                    
        </p:layoutUnit>

        <p:layoutUnit position="west" size="175" header="Nuestra Institución" collapsible="true" effect="drop" effectSpeed="">
            <p:menu> 
                <p:submenu>
                    <p:menuitem value="Quienes Somos" url="http://www.primefaces.org/showcase-labs/ui/home.jsf" />

                </p:submenu>
            </p:menu>
        </p:layoutUnit>

        <p:layoutUnit position="center">
            <ui:insert name="content">Content</ui:insert>
        </p:layoutUnit>

    </p:layout>
</h:body>

于 2013-01-04T00:25:56.397 に答える