当输入字段填写时重新启用已禁用的命令按钮

4

我需要在JSF 2.0页面上根据用户是否在文本区域中输入文本来启用/禁用按钮。

然而,虽然启用/禁用按钮可以正常工作,但操作没有被调用。

以下是代码:

<script>
                                function countChar() {
                                    var val = findElement('inputNoteTextArea');
                                    var len = val.value.length;
                                    var maxLen = 400;
                                    var charLeft;
                                    $('#charNum').text(
                                            'Note:' + maxLen + ' characters left  out of ' + maxLen);
                                    if (len >= maxLen) {
                                        val.value = val.value.substring(0, maxLen);
                                        $('#charNum').text(' you have reached the limit');
                                        document.getElementById('noteSubmitButton').disabled = false;
                                    } else if (len > 0 ){
                                        charLeft = maxLen - len;
                                        $('#charNum').text(
                                                'Note :' + charLeft
                                                        + ' characters left  out of ' + maxLen);
                                        document.getElementById('noteSubmitButton').disabled = false;
                                    } else {
                                        charLeft = maxLen - len;
                                        $('#charNum').text(
                                                'Note :' + charLeft
                                                        + ' characters left  out of ' + maxLen);
                                        document.getElementById('noteSubmitButton').disabled = true;
                                    }
                                }                               
                            </script>
                            <h:inputTextarea
                                value="#{requestScopeBean.notes}" rows="6"
                                cols="90" onkeyup="countChar();" 
                                id="inputNoteTextArea" binding="#{requestScopeBean.inputNoteText}">                                         </h:inputTextarea>
                            <div id="charNum" class="fontNormal11">
                                <span class="fontB11">Note:</span> 400 characters
                                left out of 400
                            </div>
                            <a4j:commandButton styleClass="cmdButton marR5 floatL"
                                value="Save Note" id="noteSubmitButton"
                                render="NotesForm"
                                action="#{requestScopeBean.saveNotes}"
                                title="Submit" disabled="#{requestScopeBean.enableDisableButton}"
                                oncomplete="countChar();"/>
                            <script>
                            document.getElementById('noteSubmitButton').disabled = true;
                            </script>
1个回答

5
通过JavaScript重新启用服务器端已禁用的按钮确实永远不会起作用。在处理表单提交时,JSF将再次检查disabled属性,然后创建和排队动作事件。这是为了防范篡改/黑客请求而进行的保障措施(想象一下当用户不是站点管理员时禁用的命令按钮,这样的按钮绝对不应该被JavaScript代码轻易激活,因为最终用户完全可以控制它)。
在您的情况下,此时disabled="#{bean.disabled}"仍然评估为true,使得在处理表单提交时该按钮实际上仍然被禁用,因此动作事件不会被排队,动作方法也不会被调用。这也被提及为 #5 点commandButton/commandLink/ajax action/listener method not invoked or input value not updated
那么,您应该怎么做呢?只需通过JSF启用按钮,而不是通过JavaScript。让disabled属性检查输入值是否为空。
<h:inputTextarea value="#{bean.input}" ...>
    <f:ajax event="keyup" delay="200" render="buttonId" />
</h:inputTextarea>
<h:commandButton id="buttonId" ... disabled="#{empty bean.input}" />
delay="200" 只是为了避免每键入一个字符就发送一次Ajax请求导致服务器被攻击。
或者,可以通过JavaScript初始禁用按钮,而不是通过JSF。您已经编写了正确的脚本,但它缺少表单ID,可能导致其无法工作(使用<h:form prependId="false"> 是不好的做法,您不应该这样做)。
<h:form id="formId">
    ...
    <h:commandButton id="buttonId" ... /> <!-- Note: no JSF disabled attribute! -->
</h:form>

<script>
    document.getElementById("formId:buttonId").disabled = true;
</script>

不要忘记从按钮中删除JSF disabled属性,原因如上所述。


通过移除"disabled"属性,现在动作可以被调用了。之前在页面的视图源代码中只能看到命令按钮的"onClick =“return false;”",现在其值变成了:"onclick="jsf.util.chain(this,event,"return true;","RichFaces.ajax(&quot;noteSubmitButton&quot;,event,{&quot;incId&quot;:&quot;1&quot;} )");return false;" - Walker
我也可以使用<f:ajax event ="keyup">来执行Ajax,但是在每次按键时都会出现处理循环,这可能会在添加注释时干扰用户。使用<f:ajax event ="change">仅在用户点击输入文本区域组件之外时才启用/禁用按钮,因此它看起来不太动态。因此选择使用JavaScript的方法。 - Walker

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