我有一个带有两个按钮和几个输入字段的jsf 1.2表单。第一个按钮放弃输入的值,并使用db中的值重新填充页面,第二个按钮保存输入的值。当用户在光标位于其中一个输入字段时按下回车,表单被提交并且与第一个按钮相关联的操作被执行时,会出现问题。
代码如下所示:
<h:commandButton action="#{bean.reset}" value="Reset" />
<h:commandButton action="#{bean.save}" value="Save" />
<!-- h:datatable with several h:inputText elements -->
按Enter键是否可以将特定按钮声明为默认操作?这种行为实际上是在某处指定的吗?
答案 0 :(得分:107)
这不是JSF特有的。这是HTML特有的。 HTML5 forms specification section 4.10.22.2基本上指定在输入按下时将调用与HTML DOM树中当前输入元素相同的<input type="submit">
中“树顺序”中的第一个出现<form>
元素。
基本上有两种解决方法:
使用JavaScript捕获回车键并调用所需的按钮。
<h:form onkeypress="if (event.keyCode == 13) { document.getElementById('formid:saveid').click(); return false; }">
如果你在表单中有textareas,你想把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>
声明性地识别在表单中按Enter键时应调用的按钮。
<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>
,后者依次检查是否在非textarea / button / link元素中按下了回车键,并且然后在目标元素上调用click()
。基本上与本回答中提到的第一个解决方法相同。
答案 1 :(得分:9)
我发现了一种不那么笨拙且运作良好的方法。这个想法是隐藏的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" />
这将导致一个不可见的命令按钮,根据第一个下一个提交按钮规则可以激活。
答案 2 :(得分:4)
要隐藏元素,可以使用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>
答案 3 :(得分:3)
遵循BalusC建议使用JavaScript解决问题,我写了一些jQuery代码来完成这项工作:
$(function(){
$('form').on('keypress', function(event){
if(event.which === 13 && $(event.target).is(':input')){
event.preventDefault();
$('#save').trigger('click');
}
});
});
答案 4 :(得分:3)
仅在文本输入字段(source)中忽略ENTER键:
<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>
答案 5 :(得分:0)
您可以使用h:commandLink
作为第一个按钮,并使用css设置样式,例如h:commandButton
。
例如,bootstraps "btn btn-default"
在commandLink和commandButton上看起来相同。