webentwicklung-frage-antwort-db.com.de

Standardaktion, die ausgeführt wird, wenn Sie in einem Formular die Eingabetaste drücken

Ich habe ein jsf 1.2-Formular mit zwei Schaltflächen und mehreren Eingabefeldern. Die erste Schaltfläche verwirft die eingegebenen Werte und füllt die Seite erneut mit Werten aus einer Datenbank, die zweite Schaltfläche speichert die eingegebenen Werte. Das Problem tritt auf, wenn der Benutzer die Eingabetaste drückt, während sich der Cursor in einem der Eingabefelder befindet, das Formular übermittelt wird und die mit der ersten Schaltfläche verknüpfte Aktion ausgeführt wird.

Der Code sieht so aus:

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

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

Ist es möglich, eine bestimmte Schaltfläche als Standardaktion zu definieren, wenn Sie die Eingabetaste drücken? Ist dieses Verhalten tatsächlich irgendwo angegeben?

52
Jörn Horstmann

Dies ist nicht spezifisch für JSF. Dies ist spezifisch für HTML. Die HTML5 Formularspezifikation Abschnitt 4.10.22.2 gibt im Wesentlichen an, dass das erste vorkommende <input type="submit">-Element in der "Baumreihenfolge" in demselben <form> wie das aktuelle Eingabeelement im HTML-DOM-Baum bei der Eingabepresse aufgerufen wird.

Es gibt grundsätzlich zwei Problemumgehungen:

  • Verwenden Sie JavaScript, um die Eingabetaste zu erfassen und die gewünschte Schaltfläche aufzurufen.

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

    Wenn Sie Textbereiche im Formular haben, möchten Sie den JS auf alle Eingabeelemente außerhalb des Textbereichs und nicht auf das Formular setzen. Siehe auch Verhindern, dass Benutzer ein Formular senden, indem Sie die Eingabetaste drücken.


  • Tauschen Sie die Schaltflächen in HTML aus und tauschen Sie sie mithilfe von CSS-Floats zurück.

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

    Möglicherweise ist nur eine Feinabstimmung der Pixel erforderlich. CSS natürlich in eine eigene .css-Datei schreiben; Die Verwendung von style ist eine schlechte Praxis, das obige Beispiel dient der Kürze.


Wenn Sie PrimeFaces verwenden, können Sie seit 3.2 mit <p:defaultCommand> die Schaltfläche deklarativ angeben, die beim Drücken der Eingabetaste innerhalb des Formulars aufgerufen werden soll.

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

Unter den Covers wird JavaScript für das verwendet, das einen keydown Listener an den übergeordneten <h:form> anfügt, der wiederum prüft, ob die Eingabetaste in einem Nicht-Textarea/button/link-Element gedrückt wird, und dann click() für das Zielelement aufruft. Grundsätzlich dasselbe wie in der ersten Antwort erwähnte Problemumgehung.

105
BalusC

Ich habe einen Weg gefunden, der weniger abgehackt ist und gut funktioniert. Die Idee ist ein verstecktes commandButton.

Leider kann display:none style nicht verwendet werden, da dann commandButton ignoriert wird. visibility:hidden ist nicht gut, da der Platz der Komponente reserviert wird.

Aber wir können den Stil fein abstimmen, so dass die Größe seines visuellen Erscheinungsbildes null ist mit dem folgenden CSS:

.zeroSize {
    visibility: hidden;
    padding: 0px;
    margin: 0px;
    border: 0px;
    width: 0px;
    height: 0px;
}

Und jetzt reicht es nur noch:

<h:commandButton value="" action="#{bean.save}" class="zeroSize" />

Dies führt zu einer unsichtbaren Befehlsschaltfläche, die entsprechend der Regel für die Weiterleitungsschaltfläche aktiviert werden kann.

9
icza

Zum Ausblenden von Elementen können Sie css verwenden: style="visibility: hidden"

Um die Standardaktion zu ändern, wenn Sie Primefaces verwenden, können Sie Folgendes verwenden: <p:defaultCommand target="yourButtonDefault" /> Beispiel:

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

Source: Neue Komponente als Voreinstellungen: DefaultCommand

4

Ich folgte der Empfehlung von BalusC, das Problem mithilfe von JavaScript zu lösen, und schrieb dazu etwas jQuery-Code:

$(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

Ignorieren Sie die EINGABETASTE nur in Texteingabefeldern ( 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

Sie können einen h:commandLink für die erste Schaltfläche verwenden und mit css wie h:commandButton formatieren.

Für Beispiel-Bootstraps sehen "btn btn-default" in commandLink und commandButton gleich aus.

0
Stefan