当JavaScript禁用表单时,JSF表单无法提交。

3
这是提交按钮:
<h:commandButton 
    actionListener="#{regBean.findReg}" 
    action="#{regBean.navigate}" value="Search" />

这是表单:

<h:form onsubmit="this.disabled=true;busyProcess();return true;">

如果点击提交按钮,页面会显示一个“忙碌”的图标,直到请求被处理。问题是,表单从未被提交,请求也从未到达后端。然而,如果我将“disabled”调用移除,就像这样:

<h:form onsubmit="busyProcess();return true;">

然后一切都正常工作。有什么想法吗?

6个回答

6

JSF依赖于提交按钮的名称-值对存在来在服务器端调用特定操作。如果您在提交表单之前禁用表单(至少是按钮),则请求参数映射中将没有任何信息可用,JSF将不会调用任何操作。

最好的方法是在提交后约50毫秒内禁用按钮,以引入超时。例如:

onsubmit="setTimeout(function(){document.getElementById('formId:buttonId').disabled=true;},50);busyProcess();"

顺便说一下,结尾处显式的return true;是多余的。此外,直接禁用HTML表单元素是行不通的,因为它没有disabled属性,您需要禁用按钮(如果必要,也可以禁用其他输入元素)。

以下是改进的内容:

<h:form onsubmit="busyProcess(this);">

使用

function busyProcess(form) {
    setTimeout(function() {
        for (var i = 0; i < form.elements.length; i++) {
            form.elements[i].disabled = true;
        }
    }, 50);

    // Remnant of your code here.
}

更新:既然你说它“有效”,我在各种浏览器中测试了表单的disabled属性,只有在微软IE浏览器中有效(令人惊讶),而在其他(真正的)浏览器中无效。你不想依赖于特定的浏览器,所以忘掉它并继续禁用表单的各个元素。


1
将 `this.disabled = true` 修改为 `[buttonref].disabled = true`。

感谢您的回答...但这只会禁用按钮,对吧?如果我想禁用整个页面怎么办?另外,您知道为什么这不起作用吗? - Mark
你是指整个表单吗?那么在返回 true 后,你需要这样做,例如使用 var a = this; setTimeout(function(){a.disabled = true;},0);return true - Sean Kinsey

0

我相信禁用整个表单会告诉浏览器您不希望其可提交。当您禁用单个输入元素时,这些元素在表单提交时不会被包含在发送到服务器的参数中。


0

您禁用了整个表单,只需禁用按钮即可。

此外,您还需要确保busyProcess()返回一个真值,否则提交也可能被禁用。


他想禁用所有触发第二次提交的途径 - 如“Enter”键等。 - Pointy

0
如果您不希望用户提交任何内容,可以在表单上方显示一个层,并将焦点从活动组件中移除。
另一种方法是确保 AJAX 请求使用一个公共通道,该通道具有队列,每次只处理一个请求(使用像原型等框架很容易实现)。

0

BalusC,你的超时选项非常有创意,效果很好。当我在其他浏览器中尝试“disabled”属性时,我实际上得出了同样的结论。在Opera和Firefox中,它根本没有禁用表单。我只是认为这些浏览器比IE更加多才多艺。

Sean K,仅禁用按钮而不设置超时会产生与禁用表单相同的问题,因为信息会传递到服务器。

感谢大家的帮助!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接