在表单中按 Enter 时执行的默认操作
Posted
技术标签:
【中文标题】在表单中按 Enter 时执行的默认操作【英文标题】:Default action to execute when pressing enter in a form 【发布时间】:2011-07-26 01:04:08 【问题描述】:我有一个带有两个按钮和几个输入字段的 jsf 1.2 表单。第一个按钮丢弃输入的值并使用数据库中的值重新填充页面,第二个按钮保存输入的值。当用户在光标位于其中一个输入字段时按下回车键时,会出现此问题,提交表单并执行与第一个按钮关联的操作。
代码如下所示:
<h:commandButton action="#bean.reset" value="Reset" />
<h:commandButton action="#bean.save" value="Save" />
<!-- h:datatable with several h:inputText elements -->
是否可以在按下回车时将特定按钮声明为默认操作?这种行为实际上是在某处指定的吗?
【问题讨论】:
Trinidad 在它的表单标签中提供了这样的功能。 link 嗨,Jörn,我会为只有一个输入字段的表单禁用自动提交。我猜您不希望通过在字段中按回车来提交表单。 - 顺便说一句:今年在 JAX 见? Thomas:有没有一种简单的方法可以在输入时禁用提交(可能没有 javascript,如 BalusCs 的答案)?是的,我将在美因茨的 Jax。 Primefaces 还将包含一个DefaultCommand
组件,刚刚在 primefaces 博客 (blog.primefaces.org/?p=1787) 上宣布。
【参考方案1】:
这不是 JSF 特有的。这是特定于 html 的。 HTML5 forms specification section 4.10.22.2 基本上指定“树顺序”中第一个出现的 <input type="submit">
元素与 HTML DOM 树中的当前输入元素 <form>
相同,将在按下回车时调用。
基本上有两种解决方法:
使用 JavaScript 捕捉回车键按下并调用所需的按钮。
<h:form onkeypress="if (event.keyCode == 13) document.getElementById('formid:saveid').click(); return false; ">
如果表单中有 textarea,则希望将 JS 放在所有非 textarea 输入元素上,而不是放在表单上。另见Prevent users from submitting a form by hitting Enter。
交换 HTML 中的按钮并使用 CSS 浮动将它们交换回来。
<div style="width: 100px; clear: both;">
<h:commandButton action="#bean.save" value="Save" style="float: right;" />
<h:commandButton action="#bean.reset" value="Reset" style="float: left;" />
</div>
它可能只需要一些像素微调。当然把CSS放在自己的.css
文件中;使用style
是不好的做法,上面的例子是为了简洁。
如果您碰巧使用 PrimeFaces,从 3.2 开始,您可以使用 <p:defaultCommand>
以声明方式标识在表单中按回车键时应调用的按钮。
<h:form>
<p:defaultCommand target="save" />
...
<h:commandButton id="reset" action="#bean.reset" value="Reset" />
<h:commandButton id="save" action="#bean.save" value="Save" />
</h:form>
它在幕后使用 JavaScript 将 keydown
监听器附加到父 <h:form>
上,后者依次检查是否在非文本区域/按钮/链接元素中按下了 enter 键,然后调用 @987654334 @ 在目标元素上。与此答案中提到的第一个解决方法基本相同。
【讨论】:
谢谢,我稍微修改了 javascript 以仅在文本输入字段上执行,否则在任何按钮具有焦点时按 enter 也会执行保存操作。修改后的处理程序如下所示:if (event.keyCode == 13 && event.target.nodeName == 'INPUT' && event.target.getAttribute('type') == 'text') document.getElementById('form:saveButton').click(); return false;
我注意到 defaultCommand 在 keydown 上执行 - 有没有办法将其更改为 keyup?我们遇到了一个问题,如果有时按下回车键,我们的表单会被多次提交 - 并非总是如此。【参考方案2】:
我找到了一种不那么笨拙且效果很好的方法。这个想法是隐藏的commandButton
。
很遗憾,display:none
样式无法使用,因为 commandButton
将被忽略。 visibility:hidden
不好,因为它保留了组件的空间。
但我们可以使用以下 CSS 微调样式,使其视觉外观的大小为零:
.zeroSize
visibility: hidden;
padding: 0px;
margin: 0px;
border: 0px;
width: 0px;
height: 0px;
现在只需要:
<h:commandButton value="" action="#bean.save" class="zeroSize" />
这将导致一个不可见的命令按钮,根据 first-next-submit-button 规则可以激活。
【讨论】:
当你使用标签按钮时,这不是焦点吗? @JasperdeVries 不,它不可见,因为它不可见 (visibility:hidden;
)。
该解决方案 IMO 比已批准的解决方案更好,因为它以更少的努力解决了问题所涉及的问题。【参考方案3】:
要隐藏元素,您可以使用 css:style="visibility: hidden"
如果您使用 primefaces,要更改默认操作,您可以使用:<p:defaultCommand target="yourButtonDefault" />
例如:
<h:form id="form">
<h:panelGrid columns="3" cellpadding="5">
<h:outputLabel for="name" value="Name:" style="font-weight:bold"/>
<p:inputText id="name" value="#defaultCommandBean.text" />
<h:outputText value="#defaultCommandBean.text" id="display" />
</h:panelGrid>
<p:commandButton value="Button1" id="btn1" actionListener="#defaultCommandBean.btn1Submit" ajax="false"/>
<p:commandButton value="Button2" id="btn2" actionListener="#defaultCommandBean.btn2Submit" />
<h:commandButton value="Button3" id="btn3" actionListener="#defaultCommandBean.btn3Submit" />
<p:defaultCommand target="btn3" />
</h:form>
来源:Primefaces new component: DefaultCommand
【讨论】:
将它与p:defaultCommand
。
我注意到 defaultCommand 在 keydown 上执行 - 有没有办法将其更改为 keyup?我们遇到了一个问题,如果有时按下回车键,我们的表单会被多次提交 - 并非总是如此。【参考方案4】:
按照 BalusC 使用 JavaScript 解决问题的建议,我编写了一些 jQuery 代码来完成这项工作:
$(function()
$('form').on('keypress', function(event)
if(event.which === 13 && $(event.target).is(':input'))
event.preventDefault();
$('#save').trigger('click');
);
);
代码笔:http://codepen.io/timbuethe/pen/AoKJj
【讨论】:
【参考方案5】:仅在文本输入字段中忽略 ENTER 键 (source):
<script type="text/javascript">
function stopRKey(evt)
var evt = (evt) ? evt : ((event) ? event : null);
var node = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null);
if ((evt.keyCode == 13) && (node.type=="text")) return false;
document.onkeypress = stopRKey;
</script>
【讨论】:
【参考方案6】:您可以将h:commandLink
用作第一个按钮,并使用h:commandButton
之类的css 对其进行样式设置。
例如,引导程序 "btn btn-default"
在 commandLink 和 commandButton 上看起来相同。
【讨论】:
以上是关于在表单中按 Enter 时执行的默认操作的主要内容,如果未能解决你的问题,请参考以下文章