Action par défaut à exécuter lorsque vous appuyez sur entrée dans une forme
j'ai un formulaire jsf 1.2 avec deux boutons et plusieurs champs d'entrée. Le premier bouton écarte les valeurs entrées et repopule la page avec les valeurs d'un db, le deuxième bouton sauve les valeurs entrées. Le problème se produit lorsque l'utilisateur appuie sur Entrée alors que le curseur se trouve dans l'un des champs d'entrée, que le formulaire est soumis et que l'action associée au premier bouton est exécutée.
le code ressemble à ceci:
<h:commandButton action="#{bean.reset}" value="Reset" />
<h:commandButton action="#{bean.save}" value="Save" />
<!-- h:datatable with several h:inputText elements -->
est il est possible de déclarer un bouton spécifique comme action par défaut en appuyant sur enter? Ce comportement est-il spécifié quelque part?
6 réponses
ceci n'est pas spécifique à JSF. Ceci est spécifique au HTML. L'article 4.10.22.2 de la spécification HTML5 forms specification section spécifie essentiellement que le premier élément <input type="submit">
dans l '" ordre de l'arbre "dans le même <form>
que l'élément d'entrée courant dans L'arbre principal HTML sera invoqué sur enter press.
il y a essentiellement deux solutions de rechange:
-
utilisez JavaScript pour saisir la clé enter Appuyez et invoquez le bouton désiré.
<h:form onkeypress="if (event.keyCode == 13) { document.getElementById('formid:saveid').click(); return false; }">
si vous avez des textareas dans le formulaire, vous souhaitez mettre le JS sur tous les éléments d'entrée non-textarea au lieu de sur le formulaire. Voir aussi empêcher les utilisateurs de soumettre un formulaire en appuyant sur Entrer .
-
Swap les boutons en HTML et utiliser les flotteurs CSS pour les swap en arrière.
<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>
elle ne peut besoin de quelques pixel de l'ajustement. Bien sûr, mettre CSS dans son propre fichier
.css
; utiliserstyle
est une mauvaise pratique, l'exemple ci-dessus est pour la brièveté.
si vous utilisez des PrimeFaces, depuis 3.2 vous pouvez utiliser <p:defaultCommand>
pour identifier de façon déclarative le bouton qui doit être invoqué en appuyant sur Entrée clé dans le formulaire.
<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>
il est sous le couvre en utilisant JavaScript pour ce qui attache un écouteur keydown
au parent <h:form>
qui à son tour vérifie si la touche enter est pressée dans un élément non-textarea/button/link, puis invoque click()
sur l'élément cible. Fondamentalement le même que la 1ère solution mentionnée dans cette réponse.
j'ai trouvé un moyen qui est moins hacky et fonctionne bien. L'idée est un commandButton
caché .
malheureusement display:none
ne peut pas être utilisé car alors le commandButton
sera ignoré. visibility:hidden
n'est pas bon parce qu'il garde l'espace réservé du composant.
mais nous pouvons affiner le style de sorte que la taille de son apparence visuelle sera zéro avec le CSS suivant:
.zeroSize {
visibility: hidden;
padding: 0px;
margin: 0px;
border: 0px;
width: 0px;
height: 0px;
}
et maintenant tout ce qu'il faut est:
<h:commandButton value="" action="#{bean.save}" class="zeroSize" />
il en résultera un bouton de commande invisible qui, selon la règle first-next-submit-button, peut être activé.
pour cacher des éléments, vous pouvez utiliser css: style="visibility: hidden"
pour changer l'action par défaut si vous utilisez primefaces, vous pouvez utiliser: <p:defaultCommand target="yourButtonDefault" />
Par exemple:
<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>
suite à la recommandation de BalusC de résoudre le problème en utilisant JavaScript, j'ai écrit un code jQuery pour faire le travail:
$(function(){
$('form').on('keypress', function(event){
if(event.which === 13 && $(event.target).is(':input')){
event.preventDefault();
$('#save').trigger('click');
}
});
});
ignorer la touche ENTER seulement dans les champs de saisie de texte ( 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>
Vous pouvez utiliser un h:commandLink
pour le premier bouton et le style avec css comme le h:commandButton
.
par exemple bootstraps "btn btn-default"
regardez le même sur commandLink et commandButton.