web-dev-qa-db-ja.com

フォームでEnterキーを押したときに実行するデフォルトアクション

2つのボタンといくつかの入力フィールドを持つjsf 1.2フォームがあります。最初のボタンは入力された値を破棄し、dbからの値をページに再入力し、2番目のボタンは入力された値を保存します。この問題は、カーソルが入力フィールドの1つにあるときにユーザーがEnterを押すと、フォームが送信され、最初のボタンに関連付けられたアクションが実行されるときに発生します。

コードは次のようになります。

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

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

Enterキーを押したときに特定のボタンをデフォルトのアクションとして宣言することは可能ですか?この動作は実際にどこかで指定されていますか?

55
Jörn Horstmann

これは、JSFに固有のものではありません。これはHTMLに固有です。 HTML5フォーム仕様セクション4.10.22.2 は、基本的に、HTML DOMツリーの現在の入力要素と同じ_<input type="submit">_の「ツリー順」で最初に出現する_<form>_要素を指定しますEnterを押すと呼び出されます。

基本的に2つの回避策があります。

  • JavaScriptを使用してEnterキーの押下をキャプチャし、目的のボタンを呼び出します。

    _<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>_ を使用して、フォーム内で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>
_

keydownリスナーを親_<h:form>_にアタッチするJavaScriptを使用して、非textarea/button/link要素でEnterキーが押されたかどうかを確認してから呼び出すターゲット要素のclick()。基本的に、この回答の最初に言及した回避策と同じです。

108
BalusC

ハッキングが少なく、うまく機能する方法を見つけました。アイデアは隠された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ルールに従ってアクティブにできる非表示のコマンドボタンが生成されます。

9
icza

要素を非表示にするには、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

4

JavaScriptを使用して問題を解決するというBalusCの推奨に従って、私は仕事をするためのjQueryコードを書きました。

$(function(){
  $('form').on('keypress', function(event){
    if(event.which === 13 && $(event.target).is(':input')){
        event.preventDefault();
        $('#save').trigger('click');
    }
  });
});

CodePen: http://codepen.io/timbuethe/pen/AoKJj

3
Tim Büthe

テキスト入力フィールドでのみ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>
3

最初のボタンにh:commandLinkを使用し、h:commandButtonのようなcssでスタイルを設定できます。

たとえば、ブートストラップ"btn btn-default"は、commandLinkとcommandButtonで同じように見えます。

0
Stefan