【问题标题】:PrimeFaces disable submit on pressing enter keyPrimeFaces 在按下回车键时禁用提交
【发布时间】:2015-01-23 19:01:18
【问题描述】:

PrimeFaces 禁用按 Enter 键提交。

我正在运行在 WildFly 8.2 Final 上运行的 PrimeFaces 5.1。

我有一个对话框,有两个 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; }">

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

【问题讨论】:

    标签: ajax jsf jsf-2 primefaces


    【解决方案1】:

    在您想要停止的按钮之前放置一个虚拟/隐藏按钮最适合我

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

    【讨论】:

    • 我还要添加process="@this"
    【解决方案2】:

    正如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" 中使用&lt;script&gt;,或者在p:ajaxStatusoncomplete 回调中调用函数。

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

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

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

    【讨论】:

    • 出于好奇,为什么在使用 PrimeFaces 时不合适?
    • @Nimnio,因为 UI 不再是用“这里是表单,这里是输入,这就是提交按钮”的心态构建的。现在都是通过 AJAX 提交的,通常根本没有任何实际的提交按钮。以我的经验,这种自动提交行为更频繁地破坏 UI,而不是帮助它。
    • 您的代码中有一个小错误。它不是 $(target),而是 $(event.target)。谢谢。
    【解决方案3】:

    我认为您使用 JavaScript 来捕获回车键按下并且什么都不做。

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

    参考:https://stackoverflow.com/a/5486046/201891

    return false; 如果在 HTML 中的事件处理程序属性的末尾调用,则取消跨浏览器的事件。据我所知,这种行为在任何地方都没有正式规定。

    参考:https://stackoverflow.com/a/1648854/201891

    更新

    听起来您只想在焦点位于特定字段时才禁用 Enter 键。您也可以为此编写一个 Javascript 方法并将其绑定到 onkeypress。编写一个 Javascript 方法,例如“如果按下回车键并且焦点在该字段中,则返回 false;否则,返回 true”。

    【讨论】:

    • 是的,我已经找到了如何禁用表单上的输入,但问题是我需要它来使用输入键执行一些其他操作,因为客户端要求提供热键等。所以这不是一个选项 :( 更新更多信息的问题。
    • @Kiki,我已根据您描述的要求更新了我的答案。我实际上并没有写过这样的方法,但谷歌搜索表明有很多方法可以确定字段焦点,尤其是使用 Javascript 和 JQuery。
    • 如果您的表单包含 textarea 字段,此解决方案将防止出现新行。
    【解决方案4】:

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

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

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

    我想说,控制所发生事情的最可靠方法不是通过上面解释的 onkeypress。我发现这并非在所有情况下都有效。在某些情况下,表单 onkeypress 根本不会被触发,并且您没有机会返回flase; / event.preventDefault();。我不是 100% 确定所有证明 onkeypress 没有被触发的情况,但我怀疑框架代码在某些情况下会阻止事件冒泡。

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

    因此,您可以决定的是,您将控制浏览器在何处释放其默认行为。您可以将其指向一个虚拟按钮。

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

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

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

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

    这种方法是 100% 可靠的。

    【讨论】:

      【解决方案5】:

      onkeydown 和 onchange()

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

      【讨论】:

      • 虽然它可能会起作用,但这是 per 组件,并且有点“维护密集型”,因此不是“最佳”答案。
      【解决方案6】:

      我使用了以下解决方案:

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

      这会阻止表单提交。仅当您在此表单上具有仅 ajax 行为时,它才能正常工作。

      【讨论】:

        猜你喜欢
        • 2011-01-02
        • 2022-06-14
        • 2012-01-02
        • 1970-01-01
        • 1970-01-01
        • 2011-07-09
        • 2011-08-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多