PrimeFaces 禁用按回车键提交

PrimeFaces disable submit on pressing enter key

PrimeFaces 禁用按回车键提交。

我是,运行 PrimeFaces 5.1 运行 在 WildFly 8.2 Final 上。

我有对话框,有两个 inputNumbers 和两个按钮。第一个 inputNumber 对 ajax 模糊事件进行一些计算。旁边是在 bean 中进行一些计算的按钮。问题是,当用户在焦点位于 inputNumber 时按下回车键时,按钮的动作会被触发,这真的很烦人。有没有办法禁用在对话框中使用回车键提交?

这是可以模拟我的行为的小 xhtml 对话框:

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
                xmlns:ui="http://java.sun.com/jsf/facelets"
                xmlns:h="http://java.sun.com/jsf/html"
                xmlns:p="http://primefaces.org/ui"
                xmlns:pe="http://primefaces.org/ui/extensions" >

    <p:dialog id="id_example"  header="Test dialog" 
              widgetVar="exampleDialog" modal="true" closable="true" >
        <h:form id="id_example_form">

            <p:panelGrid columns="3" styleClass="noBorders">
                <h:outputText value="Input 1:" />
                <pe:inputNumber id="Input1" value="#{exampleBean.number1}">  
                    <p:ajax event="blur" update="valueInput1" />  
                </pe:inputNumber>  

                <p:commandButton value="Check something else" action="#{exampleBean.checkForUsername()}" 
                                 update=":growl_form" />

                <h:outputText value="Input 1:" />
                <p:inputText id="valueInput1" value="#{exampleBean.number1}" />

                <p:commandButton value="Save" action="#{exampleBean.save()}"  oncomplete="PF('exampleDialog').hide();"
                                 update=":growl_form" />
            </p:panelGrid>

        </h:form>
    </p:dialog>
</ui:composition>

还有豆子:

package si.pucko.beans;

import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigInteger;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import si.pucko.util.Util;

@Named(value = "exampleBean")
@ViewScoped
public class ExampleBean implements Serializable {

    private static final long serialVersionUID = 1L;

    private BigDecimal number1;

    public ExampleBean() {
        number1 = new BigDecimal(BigInteger.ONE);
    }

    public BigDecimal getNumber1() {
        return number1;
    }

    public void setNumber1(BigDecimal number1) {
        this.number1 = number1;
    }

    public void checkForUsername() {
        Util.ShowWarning("Just testing");
    }

    public void save() {
        Util.ShowWarning("Saved");
    }
}

要注意的是我无法禁用回车键:

<h:form onkeypress="if (event.keyCode == 13) { return false; }">

因为客户端要求热键支持,输入用于提交表单,在某些情况下重新计算一些其他值等...

我认为您使用 JavaScript 捕获回车键,什么都不做。

<h:form onkeypress="if (event.keyCode == 13) { return false; }">

参考:

如果在 HTML 中的事件处理程序属性末尾调用,

return false; 会跨浏览器取消事件。据我所知,此行为在任何地方都没有正式指定。

参考:

更新

听起来您想仅在焦点位于特定字段时禁用 Enter 键。您也可以为此编写一个 Javascript 方法并将其绑定到 onkeypress。编写一个 Javascript 方法,类似于 "if the enter key was pressed and the focus is in this field, return false; otherwise, return true".

正如 answer referenced by Nimnio 所说,这是特定于 HTML 和浏览器的。

我认为这种行为在使用 PrimeFaces 时是不合适的。 对于像这样的所有形式,我更喜欢全局禁用它:

$('form').off('keypress.disableAutoSubmitOnEnter').on('keypress.disableAutoSubmitOnEnter', function(event) {
    if (event.which === $.ui.keyCode.ENTER && $(event.target).is(':input:not(textarea,:button,:submit,:reset)')) {
        event.preventDefault();
    }
});

target 检查允许其他默认行为起作用,例如通过按 Enter 在文本区域中添加换行符。

要考虑新的 ajaxically 添加的表单,您需要在每个 AJAX 请求后调用上述脚本。有多种方法可以做到这一点,例如在 p:outputPanel autoUpdate="true" 中使用 <script>,或者在 p:ajaxStatusoncomplete 回调中调用函数。

如果由于某种原因此解决方案不合适,请考虑更本地化的解决方案:

<h:form onsubmit="return false;">

在此处返回 false 将禁用非 AJAX 默认提交。

浏览器的默认行为是搜索 jQuery(":submit") 元素的表单,并在按下回车键时触发表单上列出的第一个元素。

这在调试器上看起来很奇怪,因为如果你有一个像 onclick="handle(event);".

这样的函数

您转到文本字段,按回车键,您将看到一个 "artifical" onclick 事件,该事件被传递给该表单的主要提交操作。

最可靠的方法是 in-control 发生的事情,我想说,不是通过上面解释的 onkeypress。我发现这在所有情况下都不起作用。在某些情况下,表单 onkeypress 根本不会被触发,那么您就没有机会 return flase; / event.preventDefault();.我不是 100% 确定所有情况下都不会触发 onkeypress,但我怀疑框架代码在某些情况下会阻止事件冒泡。

最终,真正发生的是您的表单是通过您的浏览器默认行为在输入文本字段中按 ENTER 提交的。提交表单的不是事件冒泡到表单。这是试图处理表单上的事件并防止那里的默认行为的缺陷。那可能为时已晚。 这很容易验证。如果您将输入文本和按键始终调整为 event.preventDefault()。 (A) 你杀了文本框没有文本被写在 texbox 上 (B) 事件仍然冒泡,但浏览器不提交表单。 所以最重要的元素是:当浏览器以默认行为运行时,它的目标是什么?

因此,您可以决定的是,您将控制浏览器释放其默认行为的位置。您可以将其定向到虚拟按钮。

这是我发现的唯一一种真正可靠的机制,可以控制当您在带有表单的文本字段上按回车键时发生的事情,即在该表单上有一个众所周知的人工按钮,例如:

<input type="submit" onclick"return false;" style="border:none; background-color: #myAppBrackgroundColor;" />

你明白了,确保浏览器将提交事件路由到你控制的按钮。

你必须要小心,尤其是 IE 是古怪的。 如果不是 IE,您可以简单地将按钮样式设置为显示:none。 由于 IE,浏览器会将默认提交操作路由到可见的提交按钮(如果存在)。 因此,您的按钮不能显示 none。您必须使其在逻辑上可见,但在物理上不可见。为此,您可以抑制边框并为您的应用程序提供合适的背景。

这种方法是 100% 可靠的。

onkeydown 和 onchange()

<h:form id="inputform">
   <p:inputText onkeydown="if (event.keyCode === 13) {onchange();return false;}"  >
      <p:ajax  update="updatearea"  /> 
   </p:inputText>
</h:form>

我使用了以下解决方案:

<h:form onsubmit="return false;">

这会阻止表单提交。仅当您在此表单上只有 ajax 行为时才有效。

在你想停止的那个按钮之前放一个 dummy/hidden 按钮最适合我

<p:commandButton style="visibility: hidden;"/> <!-- dummy hidden button to stop keyPress from firirng submit -->