Cliquez sur le bouton Entrer les déclencheurs

168

J'ai une page avec deux boutons. L'un est un <button>élément et l'autre est un <input type="submit">. Les boutons apparaissent sur la page dans cet ordre. Si je suis dans un champ de texte n'importe où dans le formulaire et que j'appuie sur <Enter>, l' clickévénement de l'élément bouton est déclenché. Je suppose que c'est parce que l'élément bouton se trouve en premier.

Je ne trouve rien qui ressemble à un moyen fiable de définir le bouton par défaut, et je ne veux pas nécessairement à ce stade. En l'absence de quelque chose de mieux, j'ai capturé une touche n'importe où sur le formulaire et, si c'était la <Enter>touche qui a été enfoncée, je la nie simplement:

$('form').keypress( function( e ) {
  var code = e.keyCode || e.which;

  if( code === 13 ) {
    e.preventDefault();
    return false; 
  }
})

Pour autant que je sache jusqu'à présent, cela semble fonctionner, mais cela semble incroyablement dur.

Est-ce que quelqu'un connaît une technique plus sophistiquée pour faire cela?

De même, y a-t-il des pièges à cette solution dont je ne suis tout simplement pas au courant?

Merci.

Rob Wilkerson
la source
1
Cela peut également se produire lors de l'utilisation de formes réactives angulaires, non seulement utiles pour JQuery, mais également pour le développement angulaire.
HDJEMAI

Réponses:

362

En utilisant

<button type="button">Whatever</button>

devrait faire l'affaire.

La raison en est qu'un bouton dans un formulaire a son type implicitement défini sur submit. Comme le dit zzzzBoz, la spécification dit que le premier buttonou inputavec type="submit"est ce qui est déclenché dans cette situation. Si vous définissez spécifiquement type="button", il est retiré de la prise en compte par le navigateur.

Chien enragé
la source
1
doux, merci, semble être des boutons dans IE8 pour moi capturant des clics <enter>, type="button"semble résoudre ce problème ... Merci! ps une idée de pourquoi c'est? ie8 traitement des boutons comme type de soumission? Bizarre.
Quang Van
3
Bonne réponse, cela indique au navigateur quels boutons ne sont pas des boutons d'envoi, afin qu'il puisse faire la bonne chose sans réorganiser le balisage.
Don Spaulding
2
La réponse de @ Leinster couvre la raison de cette bizarrerie - "Un bouton sans attribut de type est traité de la même manière qu'un bouton avec son type défini pour soumettre."
Bucket
2
Il en va de même pour <input type="submit"/>(déclenchera le clic) et <input type="button"/>(ne déclenchera pas le clic)
Marius Balčytis
1
Incroyable!! J'étais tellement confus.
Margus Pala
54

Il est important de lire les spécifications HTML pour vraiment comprendre à quel comportement il faut s'attendre:

La spécification HTML5 indique explicitement ce qui se passe dansimplicit submissions :

Le bouton par défaut d'un élément de formulaire est le premier bouton d'envoi dans l'ordre de l'arborescence dont le propriétaire du formulaire est cet élément de formulaire.

Si l'agent utilisateur prend en charge le fait de permettre à l'utilisateur de soumettre un formulaire implicitement (par exemple, sur certaines plates-formes, le fait d'appuyer sur la touche "Entrée" alors qu'un champ de texte est focalisé soumet implicitement le formulaire), alors le faire pour un formulaire dont le bouton par défaut a une activation définie Le comportement doit amener l'agent utilisateur à exécuter des étapes d'activation de clic synthétique sur ce bouton par défaut.

Cela n'a pas été rendu explicite dans la spécification HTML4, mais les navigateurs ont déjà implémenté ce qui est décrit dans la spécification HTML5 (c'est pourquoi il est inclus explicitement).

Modifier pour ajouter:

La réponse la plus simple à laquelle je puisse penser est de mettre votre bouton d' [type="submit"]envoi en tant que premier élément du formulaire, d'ajouter un rembourrage au bas du formulaire avec css et de positionner absolument le bouton d'envoi en bas à l'endroit où vous le souhaitez.

zzzzBov
la source
Là, je maudissais IE, il s'avère que c'était mon balisage bâclé tout du long! À votre santé!
Shawson
2
Wow ... Merci bon monsieur. C'était une découverte accidentelle. Je ne pouvais même pas comprendre pourquoi un événement de clic était déclenché en appuyant sur la touche Entrée, mais votre citation m'a conduit à w3.org/TR/html5/forms.html#implicit-submission
chemoish
Le lien est rompu. Je pense que w3c.github.io/html/sec-forms.html#implicit-submission est la nouvelle URL.
TJ.
22

Je ne pense pas que vous ayez besoin de javascript ou de CSS pour résoudre ce problème.

Selon la spécification html 5 pour les boutons un bouton sans attribut de type est traité de la même manière qu'un bouton avec son type défini sur «soumettre», c'est-à-dire comme un bouton pour soumettre son formulaire contenant. La définition du type de bouton sur "bouton" devrait empêcher le comportement que vous voyez.

Je ne suis pas sûr de la prise en charge du navigateur pour cela, mais le même comportement a été spécifié dans la spécification html 4.01 pour les boutons, donc je pense que c'est assez bon.

Leinster
la source
13

En appuyant sur «Entrée» sur le focus, <input type="text">vous déclenchez l'événement «clic» sur le premier élément positionné: <button>ou <input type="submit">. Si vous appuyez sur «Entrée» <textarea>, vous créez simplement une nouvelle ligne de texte.

Voir l'exemple ici .

Votre code empêche de créer une nouvelle ligne de texte <textarea>, vous devez donc attraper une touche uniquement pour <input type="text">.

Mais pourquoi avez-vous besoin d'appuyer Entersur le champ de texte? Si vous voulez soumettre le formulaire en appuyant sur 'Entrée', mais que le <button>doit rester le premier dans la mise en page, jouez simplement avec le balisage: mettez le <input type="submit">code avant le <button>et utilisez CSS pour enregistrer la mise en page dont vous avez besoin.

Attraper 'Enter' et enregistrer le balisage:

$('input[type="text"]').keypress(function (e) {
    var code = e.keyCode || e.which;
    if (code === 13)
    e.preventDefault();
    $("form").submit(); /*add this, if you want to submit form by pressing `Enter`*/
});
Feniks502
la source
L'instruction if ne devrait-elle pas avoir une accolade pour exécuter les deux instructions uniquement lorsque vous appuyez sur Entrée? Sinon, la soumission se produira à chaque pression de touche. Cela me rappelle l'échec. :)
danmiser
13

Partout où vous utilisez un <button>élément par défaut, il considère ce bouton, type="submit"donc si vous définissez le bouton, type="button"il ne le considérera pas comme un <button>bouton d'envoi.

Ram Thota
la source
2

Appuyer sur Entrée dans le champ de texte d'un formulaire soumettra, par défaut, le formulaire. Si vous ne voulez pas que cela fonctionne de cette façon, vous devez capturer la touche Entrée et la consommer comme vous l'avez fait. Il n'y a aucun moyen de contourner cela. Cela fonctionnera de cette façon même s'il n'y a pas de bouton présent dans le formulaire.

Sparafusile
la source
4
Je ne pense pas que le problème soit que le formulaire se soumette, c'est qu'il déclenche l' clickaction sur les éléments de bouton que vous souhaitez est une conséquence involontaire
Martin Jespersen
Vous avez raison. Dans tous les cas, le résultat est le même: vous devez capturer la touche Entrée pour éviter les soumissions de formulaires indésirables.
Sparafusile
2

Vous pouvez utiliser javascript pour bloquer la soumission du formulaire jusqu'au moment opportun. Un exemple très grossier:

<form onsubmit='return false;' id='frmNoEnterSubmit' action="index.html">

    <input type='text' name='txtTest' />

    <input type='button' value='Submit' 
        onclick='document.forms["frmNoEnterSubmit"].onsubmit=""; document.forms["frmNoEnterSubmit"].submit();' />

</form>

Appuyer sur Entrée déclenchera toujours la soumission du formulaire, mais le javascript l'empêchera de se soumettre jusqu'à ce que vous appuyiez réellement sur le bouton.

Dave
la source
2

Exemple de dom

  <button onclick="anotherFoo()"> Add new row</button>
  <input type="text" name="xxx" onclick="foo(event)">

javascript

function foo(event){
   if(event.which == 13 || event.keyCode == 13) // for crossbrowser
   {
     event.preventDefault(); // this code prevents other buttons triggers use this
     // do stuff
   }
}

function anotherFoo(){
  // stuffs.
}

si vous n'utilisez pas preventDefault (), d'autres boutons seront déclenchés.

Mehmet Ali Kuş
la source
0

Je le ferais comme suit: Dans le gestionnaire de l'événement onclick du bouton (ne pas soumettre), vérifiez le code clé de l'objet événement. Si c'est "enter", je retournerais false.

Satyajit
la source
Ce code clé est toujours transmis comme s'il s'agissait d'un clic. C'est là que réside le problème. :-)
Rob Wilkerson
Ensuite, je suppose que vous le faites à la dure - gérez également l'événement onkeydown sur le bouton. Le gestionnaire recevra un keyEvent; vérifiez le keyCode -> if 13, preventDefault. De cette façon, vous pouvez également laisser les utilisateurs appuyer sur Entrée sur ce bouton sans l'effet secondaire de l'exécution de l'événement de clic.
Satyajit
0

Ma situation a deux Submitboutons dans l'élément de formulaire: Updateet Delete. Le Deletebouton supprime une image et le Updatebouton met à jour la base de données avec les champs de texte du formulaire.

Étant donné que le Deletebouton était le premier dans le formulaire, il s'agissait du bouton par défaut sur la Enterclé. Pas ce que je voulais. L'utilisateur s'attend à pouvoir frapper Enteraprès avoir modifié certains champs de texte.

J'ai trouvé ma réponse à la configuration du bouton par défaut ici :

<form action="/action_page.php" method="get" id="form1">
  First name: <input type="text" name="fname"><br>
  Last name: <input type="text" name="lname"><br>
</form>
<button type="submit" form="form1" value="Submit">Submit</button>

Sans utiliser de script, j'ai défini le formulaire auquel appartient chaque bouton en utilisant le <button> form="bla" attribut. J'ai défini le Deletebouton sur un formulaire qui n'existe pas et le Updatebouton que je voulais déclencher sur la Enterclé sur le formulaire dans lequel l'utilisateur se trouverait lors de la saisie de texte.

C'est la seule chose qui a fonctionné pour moi jusqu'à présent.

Dan Vachon
la source
1
Veuillez vérifier comment répondre sur stackoverflow
Morse
0

Vous pouvez faire quelque chose comme ça.

liez votre événement à une fonction commune et appelez l'événement en appuyant sur une touche ou en cliquant sur un bouton.

par exemple.

function callME(event){
    alert('Hi');
}



$('button').on("click",callME); 
$('input ').keypress(function(event){
  if (event.which == 13) {
    callME(event);
  }
});
nouveau développeur
la source
-1

J'ai ajouté un bouton de type "soumettre" comme premier élément du formulaire et je l'ai rendu invisible ( width:0;height:0;padding:0;margin:0;border-style:none;font-size:0;). Fonctionne comme une actualisation du site, c'est à dire que je ne fais rien lorsque le bouton est enfoncé sauf que le site est à nouveau chargé. Pour moi ça marche bien ...

torabe
la source