58

我有一个带有两个按钮和几个输入字段的 jsf 1.2 表单。第一个按钮丢弃输入的值并使用数据库中的值重新填充页面,第二个按钮保存输入的值。当用户在光标位于其中一个输入字段时按下回车键时,会出现问题,提交表单并执行与第一个按钮关联的操作。

代码如下所示:

<h:commandButton action="#{bean.reset}" value="Reset" />
<h:commandButton action="#{bean.save}" value="Save" />

<!-- h:datatable with several h:inputText elements -->

是否可以在按 Enter 时将特定按钮声明为默认操作?这种行为实际上是在某处指定的吗?

4

6 回答 6

115

这不是 JSF 特有的。这是特定于 HTML 的。HTML5 表单规范第4.10.22.2 节基本上指定<input type="submit">在“树顺序”中与<form>HTML DOM 树中的当前输入元素相同的第一个出现的元素将在回车时被调用。

基本上有两种解决方法:

  • 使用 JavaScript 捕获输入键并调用所需的按钮。

    <h:form onkeypress="if (event.keyCode == 13) { document.getElementById('formid:saveid').click(); return false; }">
    

    如果表单中有文本区域,则希望将 JS 放在所有非文本区域输入元素上,而不是放在表单上。另请参阅按 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 键,然后click()在目标元素上调用。与此答案中第一个提到的解决方法基本相同。

于 2011-03-30T12:06:11.353 回答
10

我找到了一种不那么hacky并且效果很好的方法。这个想法是隐藏的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 规则可以激活该按钮。

于 2014-05-12T12:00:09.847 回答
5

要隐藏元素,您可以使用 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 新组件:DefaultCommand

于 2015-03-01T06:48:59.257 回答
3

按照 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

于 2014-01-20T13:22:41.957 回答
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>
于 2015-04-29T12:45:42.827 回答
0

您可以将 ah:commandLink用作第一个按钮,并使用 css 对其进行样式设置,例如h:commandButton.

例如,引导程序"btn btn-default"在 commandLink 和 commandButton 上看起来相同。

于 2018-03-02T12:54:11.723 回答