ajax PrimeFaces 在按下 Enter 键时禁用提交

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28116894/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-06 10:27:37  来源:igfitidea点击:

PrimeFaces disable submit on pressing enter key

ajaxjsfjsf-2primefaces

提问by Kiki

PrimeFaces disable submit on pressing enter key.

PrimeFaces 在按下 Enter 键时禁用提交。

I'm, running PrimeFaces 5.1 running on WildFly 8.2 Final.

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

I have dialog, with two inputNumbers and two buttons. And the first inputNumber does some calculation on ajax blur event. Next to it is button which does some calculation in bean. And the problem is that when users press enter while focus is in inputNumber the button's action gets fired and it's really annoying. Is there a way to disable submitting with enter key on dialog?

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

Here is small xhtml dialog which can simulate my behavior:

这是可以模拟我的行为的小 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>

And the bean:

还有豆子:

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");
    }
}

The catch is i can't disable enter key with:

问题是我无法禁用输入键:

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

Because client asked for hotkeys support and enter is used for submiting forms, recalculation some other values in some cases etc...

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

回答by DavidS

I think you use JavaScript to capture the enter key press and do nothing.

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

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

Ref: https://stackoverflow.com/a/5486046/201891

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

return false;cancels an event across browsers if called at the end of an event handler attribute in the HTML. This behaviour is not formally specified anywhere as far as I know.

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

Ref: https://stackoverflow.com/a/1648854/201891

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

Update

更新

It sounds like you want to disable the Enter key only when focus is in a particular field. You can write a Javascript method for that too and bind it to onkeypress. Write a Javascript method something like "if the enter key was pressed and the focus is in this field, return false; otherwise, return true".

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

回答by Vsevolod Golovanov

As the answer referenced by Nimniosays, this is specific to HTML and browsers.

正如Nimnio 引用答案所说,这是特定于 HTML 和浏览器的。

I consider this behavior to be inappropriate when using PrimeFaces. I prefer to disable it globally, for all forms like this:

我认为在使用 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();
    }
});

The targetcheck allows the other default behaviors to work, like adding a line break in a textarea by pressing Enter.

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

To take into account new ajaxically added forms you'll need to call the above script after every AJAX request. There are multiple ways to do that, such as a <script>in a p:outputPanel autoUpdate="true", or calling a function in a p:ajaxStatus's oncompletecallback.

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

If this solution is not appropriate for some reason then consider the more localized one:

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

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

Returning falsehere disables the non-AJAX default submit.

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

回答by 99Sono

It is default browser behavior to hunt a form for jQuery(":submit") elements and trigger the first listed on the form, when the enter key is pressed.

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

this will look strange on debugger, because if you have a function such as onclick="handle(event);".

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

You go to the text field, hit enter, and you will see an "artifical" onclick event with being passed to your primary submit action for that form.

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

The surest way to be in-control of what happens, I would say, is not by means of onkeypress as explained above. I found that to not work in all cases. On soame cases the form onkeypress simply does not get triggered, and you do not have then the opportunity to return flase; / event.preventDefault();. I am not 100% sure of all cases that justfied the onkeypress not getting triggered, but I suspect framework code preventing event bubbling in some instances.

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

Ultimately, what is really happening is your form is being submitted by your browser default behavior on ENTER withing input text field. It is not the bubling of the event to the form that submits the form. That is the flaw of trying to handle the event on the form and preventing default behavior there. That might just be too late. And this is very easy to verify. If you tune youe inpu text and onkeypress always to event.preventDefault(). (A) you kill the textbox no text gets written on the texbox (B) The event still bubles up, but the browser does not submit the form anyway. So the most important element of all is: where is the browser aiming at when it acts with the default behavior?

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

So what you can decide instead is that what you will take control of where the browser unleashes its default behavior. You can direct it to a dummy button.

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

This is the one and only one mechanism I have found to be really reliable to be in control of what happens when you hit enter on a text field withing a form is to have on that form a well known artifical button, e.g.:

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

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

You get the idea, to make sure that the submit event is being routed by the browser to a button under your control.

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

You have to be careful, IE in particular is quirky. If not for IE, you could simply style your button as display: none. Because of IE, the browser will route the default submit action to a visible submit button, if one exists. Therefore, your button cannot be in display none. You have to make it logically visible, but phsysically invisible. For that you supress the border and give it an appropriate background for your application.

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

This method is 100% reliable.

这种方法是 100% 可靠的。

回答by ibrahimyanik

onkeydown and onchange()

onkeydown 和 onchange()

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

回答by Dmitry Trifonov

I used following solution:

我使用了以下解决方案:

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

This prevents form submit. It works well only in case if you have ajax only behavior on this form.

这可以防止表单提交。只有在此表单上只有 ajax 行为的情况下,它才能很好地工作。

回答by user6627139

Putting a dummy/hidden button before the one you want to stop works best for me

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

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

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