如何在不阻止动作和actionListener被调用的情况下禁用h:commandButton?

edh*_*ges 3 java jsf jsp jsf-2

我有一个简单的脚本标记,其中包含一个函数,我将其包含在html主体的底部.此脚本只是禁用提交按钮.然后我有一个onclick调用该函数的事件.

我在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>
Run Code Online (Sandbox Code Playgroud)

任何帮助将不胜感激.该做的,不工作的页面之间的唯一区别是,actionactionListeners不同类型的咖啡豆和一些有f:params和别人不一样.

Bal*_*usC 7

我知道你的具体问题是,一旦禁用按钮,就不会调用backing bean的动作了吗?这可能是真的.JSF根据与UICommand组件的HTML表示关联的请求参数名称的存在来确定要调用的操作.但是,当禁用HTML输入/按钮元素时,其name = value将不会作为请求参数发送(因此JSF将无法确定要调用的操作).该onclick属性即在发送表单提交请求之前调用.

表单提交请求发送到服务器端,您希望禁用该按钮.到目前为止给出的代码,唯一的方法是在button.disabled=true超过50ms后调用.

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

如果您正在使用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);
Run Code Online (Sandbox Code Playgroud)

在它适合您的情况下,该按钮很可能是一个启用了ajax的按钮.事先禁用按钮没有副作用.


map*_*aft 6

您应该在click事件之后从服务器端actionListener设置commandButton组件的启用状态.

<h:commandButton disabled="#{managedBean.someBooleanPropertyThatWasToggledInTheEvent}" />
Run Code Online (Sandbox Code Playgroud)

您可以在调用服务器端事件后简单地设置托管属性,并在页面刷新时禁用它.

更新:

我刚刚意识到OP有一个完全不同的问题.用户不耐烦并单击按钮而不是等待回发.但是,禁用命令按钮有时会阻止调用服务器端操作.

解决此问题的正确方法是在页面上放置一个绝对位置div覆盖,其z-index高于页面上任何其他元素.这样可以防止在叠加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;
}
Run Code Online (Sandbox Code Playgroud)

使用jQuery fadeToggle功能的Javascript切换功能

function toggleLoadingOverlay() {
  var div = jQuery('.div-overlay');
  div.fadeToggle(150);
}
Run Code Online (Sandbox Code Playgroud)

**单击按钮时将发生的JSF commandButton onclick事件(并假设事件传播未被中断)**

<h:commandButton onclick="toggleLoadingOverlay();" action="..." />
Run Code Online (Sandbox Code Playgroud)