3

html本文の下部に関数を含む単純なスクリプトタグがあります。このスクリプトは、送信ボタンを無効にするだけです。次にonclick、関数を呼び出すイベントがあります。

このコードは5つの異なるページにあり、5つのうち3つで機能します。

コードは次のとおりです。

<!-- more non-important html -->

<h:commandButton id="buttonToDisable" 
    value="some text"
    action="#{myBean.myBeansAction}" 
    actionListener="#{myBean.myBeansActionListener}" 
    onclick="disableButton()">

    <!-- I also have an f:param in some of these pages but I didn't 
    think that would matter -->

</h:commandButton>

<!--  more non-important html -->

<script>
    function disabledButton() {
        document.getElementById("myForm:buttonToDisable").disabled = 'true';
    }
</script>

どんな助けでも大歓迎です。動作するページと動作しないページの唯一の違いは、actionactionListenersは異なるタイプのBeanであり、あるものf:paramsとないものがあることです。

4

3 に答える 3

7

あなたの具体的な問題は、ボタンを無効にするとバッキングBeanのアクションが呼び出されないことだと理解していますか?それは非常に真実である可能性があります。UICommandJSFは、コンポーネントのHTML表現に関連付けられた要求パラメーター名の存在に基づいて、呼び出されるアクションを決定します。ただし、HTML入力/ボタン要素が無効になっている場合、そのname = valueは要求パラメーターとしてまったく送信されません(したがって、JSFは呼び出されるアクションを判別できません)。onclickつまり、この属性は、フォーム送信要求が送信される直前に呼び出されます。

フォーム送信リクエストがサーバー側に送信された、ボタンを無効にします。これまでに提供されたコードでは、唯一の方法はbutton.disabled=true、約50ミリ秒のタイムアウト後に呼び出すことです。

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

ただし、JSF 2.0を使用している場合は<f:ajax>、別の、より堅牢でグローバルな方法があります。

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

それがあなたのために働いた場合、ボタンはおそらくajax対応のボタンでした。事前にボタンを無効にしても副作用はありません。

于 2012-07-31T18:42:52.463 に答える
6

クリックイベントの後、サーバー側のactionListenerからcommandButtonコンポーネントの有効なステータスを設定する必要があります。

<h:commandButton disabled="#{managedBean.someBooleanPropertyThatWasToggledInTheEvent}" />

サーバー側のイベントを呼び出した後、管理プロパティを設定するだけで、ページの更新時に無効になります。

アップデート:

OPにはまったく別の問題があることに気づきました。ユーザーはせっかちでボタンをクリックし、ポストバックを待ちません。ただし、コマンドボタンを無効にすると、サーバー側のアクションが呼び出されなくなる場合があります。

これを解決する正しい方法は、ページ上の他のどの要素よりも高いz-indexを使用して、ページ全体に絶対位置divオーバーレイを配置することです。これにより、オーバーレイdiv以外でクリックが発生するのを防ぐことができます。次に例を示します。

CSSスタイル

.div-overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: #000;
    filter:alpha(opacity=50);
    -moz-opacity:0.5;
    -khtml-opacity: 0.5;
    opacity: 0.5;
    z-index: 10000;
}

jQueryのfadeToggle機能を利用したJavascriptトグル関数

function toggleLoadingOverlay() {
  var div = jQuery('.div-overlay');
  div.fadeToggle(150);
}

**ボタンがクリックされると発生するJSFcommandButtononclickイベント(およびイベントの伝播が中断されていないことを前提としています)**

<h:commandButton onclick="toggleLoadingOverlay();" action="..." />
于 2012-07-31T17:20:22.873 に答える
0

@maple_shaftによって提案された解決策を試しましたが、opaque / toggleFade()divは、opacity = 0の場合でも、常にキーストロークを吸収しました。これが私の答えです:

<script type="text/javascript">
    function overlayToFront()
    {
        document.getElementById("div-overlay").style.zIndex = "10000";
    }
</script>

ページ:

<... id="form1"> <!-- in the existing code, some component with id="form1" in my case it was a:form -->
    <div id="div-overlay" 
        style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: #000;
            filter:alpha(opacity=0); -moz-opacity:0.0; -khtml-opacity: 0.0; opacity: 0.0;
            z-index: -10000; cursor: wait;">
        <!-- lay out a transparent div in the background.
        Buttons with onclick="overlayToFront();" can prevent double-clicks by covering the whole GUI when this div gets moved to the front
        Currently only used in one place, but any button with reRender="form1" should be able to to this
        -->
    </div>
    <div id="div-base-layer"
        style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: #000;
            filter:alpha(opacity=0); -moz-opacity:0.0; -khtml-opacity: 0.0; opacity: 0.0;
            z-index: -1;" > <!-- rendered "on top of" div-overlay, so cursor does not change when moving off the legacy part of the page -->
    </div>
    <div>
        <!-- this is where the legacy part of the page, the contents of the component with id="form1" goes. it did not have a position: attribute in the original code so z-index does not affect it -->
    </div>
</ ...> <!-- end of tag with id="form1"  -->
于 2017-04-05T20:05:49.043 に答える