web-dev-qa-db-fra.com

Empêcher les utilisateurs de soumettre un formulaire en appuyant sur Entrée

J'ai un sondage sur un site Web, et il semble y avoir quelques problèmes avec les utilisateurs qui cliquent sur entrer (je ne sais pas pourquoi) et soumettant accidentellement le sondage (formulaire) sans cliquer sur le bouton d'envoi. Est-ce qu'il y a un moyen d'éviter cela?

J'utilise HTML, PHP 5.2.9 et jQuery pour l'enquête.

697
DForck42

Vous pouvez utiliser une méthode telle que

$(document).ready(function() {
  $(window).keydown(function(event){
    if(event.keyCode == 13) {
      event.preventDefault();
      return false;
    }
  });
});

En lisant les commentaires sur le message original, pour le rendre plus utilisable et permettre aux gens d’appuyer sur Enter s'ils ont rempli tous les champs:

function validationFunction() {
  $('input').each(function() {
    ...

  }
  if(good) {
    return true;
  }
  return false;
}

$(document).ready(function() {
  $(window).keydown(function(event){
    if( (event.keyCode == 13) && (validationFunction() == false) ) {
      event.preventDefault();
      return false;
    }
  });
});
810
user83632

Interdit la clé d'entrée n'importe où

Si vous n'avez pas de _<textarea>_ dans votre formulaire, ajoutez simplement ce qui suit à votre _<form>_:

_<form ... onkeydown="return event.key != 'Enter';">
_

Ou avec jQuery:

_$(document).on("keydown", "form", function(event) { 
    return event.key != "Enter";
});
_

Cela entraînera que chaque pression sur une touche du formulaire sera vérifiée sur le key. Si ce n'est pas Enter, alors il retournera true et tout continuera comme d'habitude. Si c'est Enter, alors il retournera false et tout s'arrêtera immédiatement, ainsi le formulaire ne sera pas soumis.

L'événement keydown est préféré à keyup , car keyup est trop tard pour bloquer l'envoi du formulaire. Historiquement, il y avait aussi keypress , mais il est déconseillé, de même que KeyboardEvent.keyCode . Vous devez utiliser KeyboardEvent.key à la place qui renvoie le nom de la touche enfoncée. Lorsque la case Enter est cochée, la case 13 (entrée normale) et 108 (entrée pavé numérique) est alors cochée.

Notez que $(window) comme suggéré dans d'autres réponses au lieu de $(document) ne fonctionne pas pour keydown/keyup dans IE <= 8, ce n'est donc pas un bon choix si vous souhaitez couvrir ces utilisateurs pauvres. ainsi que.

Autoriser la clé d'entrée sur les zones de texte uniquement

Si vous avez un _<textarea>_ dans votre formulaire (ce qui bien sûr doit accepter la touche Entrée), ajoutez le gestionnaire de touches dans chaque entrée individuelle. élément qui n'est pas un _<textarea>_.

_<input ... onkeydown="return event.key != 'Enter';">
<select ... onkeydown="return event.key != 'Enter';">
...
_

Pour réduire le nombre de problèmes, il est préférable de le faire avec jQuery:

_$(document).on("keydown", ":input:not(textarea)", function(event) {
    return event.key != "Enter";
});
_

Si d'autres fonctions de gestionnaire d'événements sont attachées à ces éléments d'entrée et que vous souhaitez également les appeler à la touche Entrée pour une raison quelconque, empêchez le comportement par défaut de l'événement au lieu de renvoyer la valeur false afin qu'il puisse se propager correctement à d'autres gestionnaires.

_$(document).on("keydown", ":input:not(textarea)", function(event) {
    if (event.key == "Enter") {
        event.preventDefault();
    }
});
_

Autoriser la clé d'entrée sur les zones de texte et les boutons d'envoi uniquement

Si vous souhaitez autoriser la touche Entrée sur les boutons de soumission _<input|button type="submit">_ également, vous pouvez toujours affiner le sélecteur comme indiqué ci-dessous.

_$(document).on("keydown", ":input:not(textarea):not(:submit)", function(event) {
    // ...
});
_

Notez que _input[type=text]_ comme suggéré dans d'autres réponses ne couvre pas les entrées HTML5 non textuelles, ce n'est donc pas un bon sélecteur.

554
BalusC

J'ai dû intercepter les trois événements liés à l'appui sur les touches afin d'empêcher l'envoi du formulaire:

    var preventSubmit = function(event) {
        if(event.keyCode == 13) {
            console.log("caught ya!");
            event.preventDefault();
            //event.stopPropagation();
            return false;
        }
    }
    $("#search").keypress(preventSubmit);
    $("#search").keydown(preventSubmit);
    $("#search").keyup(preventSubmit);

Vous pouvez combiner tout ce qui précède dans une version compacte de Nice:

    $('#search').bind('keypress keydown keyup', function(e){
       if(e.keyCode == 13) { e.preventDefault(); }
    });
64
Upgradingdave

Section 4.10.22.2 Soumission implicite de la spécification HTML5 du W3C indique:

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

Si l'agent utilisateur prend en charge le fait de laisser l'utilisateur soumettre un formulaire implicitement (par exemple, sur certaines plates-formes, appuyer sur la touche "Entrée" lorsqu'un champ de texte est activé de manière implicite), le faire pour un formulaire dont bouton par défaut a défini comportement d'activation doit obliger l'agent d'utilisateur à exécuter les étapes d'activation de clic synthétique sur celui-ci bouton par défaut .

Remarque: Par conséquent, si le bouton par défaut est désactivé, le formulaire n'est pas soumis lorsqu'un tel mécanisme de soumission implicite est utilisé. (Un bouton n'a pas comportement d'activation lorsqu'il est désactivé.)

Par conséquent, un moyen conforme aux normes permettant de désactiver toute soumission implicite du formulaire consiste à placer un bouton d'envoi désactivé en tant que premier bouton d'envoi du formulaire:

<form action="...">
  <!-- Prevent implicit submission of the form -->
  <button type="submit" disabled style="display: none" aria-hidden="true"></button>

  <!-- ... -->

  <button type="submit">Submit</button>
</form>

Une caractéristique intéressante de cette approche est que cela fonctionne sans JavaScript ; Que JavaScript soit activé ou non, un navigateur Web conforme aux normes est requis pour empêcher la soumission implicite de formulaires.

52
Daniel Trebbien

Si vous utilisez un script pour effectuer la soumission, vous pouvez ajouter la ligne "return false" au gestionnaire onsubmit, comme ceci:

<form onsubmit="return false;">

L'appel de submit () sur le formulaire à partir de JavaScript ne déclenchera pas l'événement.

47
Tom Hubbard

Utilisation:

$(document).on('keyup keypress', 'form input[type="text"]', function(e) {
  if(e.keyCode == 13) {
    e.preventDefault();
    return false;
  }
});

Cette solution fonctionne sur tous les formulaires d'un site Web (également sur les formulaires insérés avec Ajax), empêchant uniquement Enters dans les textes d'entrée. Placez-le dans une fonction de préparation de document et oubliez ce problème pour la vie.

22
Buzogany Laszlo

Au lieu d'empêcher les utilisateurs d'appuyer sur Enter, ce qui peut paraître anormal, vous pouvez laisser le formulaire en l’état et ajouter une validation client supplémentaire: lorsque l’enquête n’est pas terminée, le résultat n’est pas envoyé au serveur et l’utilisateur reçoit un joli message indiquant ce qui doit être terminé Complétez le formulaire. Si vous utilisez jQuery, essayez le plugin Validation:

http://docs.jquery.com/Plugins/Validation

Cela nécessitera plus de travail que de saisir les Enter bouton, mais il fournira sûrement une expérience utilisateur plus riche.

20
bbmud

Je ne peux pas encore commenter, alors je vais poster une nouvelle réponse

La réponse acceptée est ok-ish, mais cela n’arrêtait pas de soumettre le pavé numérique entré. Au moins dans la version actuelle de Chrome. J'ai dû modifier la condition de code d'activation en ceci, puis cela fonctionne.

if(event.keyCode == 13 || event.keyCode == 169) {...}
18
sparklos

Une jolie petite solution jQuery simple:

$("form").bind("keypress", function (e) {
    if (e.keyCode == 13) {
        return false;
    }
});
17
Eonasdan

C'est ma solution pour atteindre l'objectif, c'est propre et efficace.

$('form').submit(function () {
  if ($(document.activeElement).attr('type') == 'submit')
     return true;
  else return false;
});
12
Developer

Une approche complètement différente:

  1. Le premier <button type="submit"> du formulaire sera activé en appuyant sur Enter.
  2. Ceci est vrai même si le bouton est caché avec style="display:none;
  3. Le script de ce bouton peut renvoyer false, ce qui annule le processus de soumission.
  4. Vous pouvez toujours avoir un autre <button type=submit> pour soumettre le formulaire. Il suffit de retourner true pour transférer la soumission en cascade.
  5. Pressage Enter pendant que le bouton de soumission réel est activé, le bouton de soumission réel est activé.
  6. Pressage Enter dans <textarea> ou d’autres contrôles de formulaire se comporteront normalement.
  7. Pressage Enter à l'intérieur de <input> les commandes de formulaire déclenchent le premier <button type=submit>, qui retourne false, et il ne se passe donc rien.

Ainsi:

<form action="...">
  <!-- insert this next line immediately after the <form> opening tag -->
  <button type=submit onclick="return false;" style="display:none;"></button>

  <!-- everything else follows as normal -->
  <!-- ... -->
  <button type=submit>Submit</button>
</form>
10
Erics

Donner au formulaire une action de 'javascript: void (0);' semble faire l'affaire

<form action="javascript:void(0);">
<input type="text" />
</form>
<script>
$(document).ready(function() {
    $(window).keydown(function(event){
        if(event.keyCode == 13) {
    alert('Hello');
        }
    });
});
</script>
8
sidarcy
  1. Ne pas utiliser type = "submit" pour les entrées ou les boutons.
  2. Utilisez type = "button" et utilisez js [Jquery/angular/etc] pour envoyer le formulaire au serveur.
6
Irfan Ashraf

J'avais besoin d'empêcher que seules des entrées spécifiques soient soumises. J'ai donc utilisé un sélecteur de classe pour que cette fonctionnalité soit "globale" chaque fois que j'en ai besoin.

<input id="txtEmail" name="txtEmail" class="idNoEnter" .... />

Et ce code jQuery:

$('.idNoEnter').keydown(function (e) {
  if (e.keyCode == 13) {
    e.preventDefault();
  }
});

Alternativement, si le raccourci clavier est insuffisant:

$('.idNoEnter').on('keypress keydown keyup', function (e) {
   if (e.keyCode == 13) {
     e.preventDefault();
   }
});

Quelques notes:

Modifier diverses bonnes réponses ici, le Enter La clé semble fonctionner pour keydown sur tous les navigateurs. Pour l’alternative, j’ai mis à jour bind() à la méthode on().

Je suis un grand fan de sélecteurs de classe, pesant tous les pour et les contre et les discussions de performance. Ma convention de dénomination est 'idSomething' pour indiquer que jQuery l'utilise comme identifiant, pour le séparer du style CSS.

6
goodeye

Ne pas mettre un bouton d'envoi pourrait faire l'affaire. Il suffit de mettre un script à l’entrée (type = button) ou d’ajouter eventListener si vous voulez qu’il soumette les données du formulaire.

Plutôt utiliser cette

<input type="button">

que d'utiliser cette

<input type="submit">
5
Jimwel Anobong

Vous pouvez créer une méthode JavaScript pour vérifier si le Enter la touche a été touchée et, le cas échéant, pour arrêter la soumission.

<script type="text/javascript">
  function noenter() {
  return !(window.event && window.event.keyCode == 13); }
</script>

Il suffit d'appeler cela sur la méthode submit.

5
Brandon

Je pense qu'il est bien couvert avec toutes les réponses, mais si vous utilisez un bouton avec du code de validation JavaScript, vous pouvez simplement définir le formulaire onkeypress du formulaire pour Enter afin d'appeler votre soumission comme prévu:

<form method="POST" action="..." onkeypress="if(event.keyCode == 13) mySubmitFunction(this); return false;">

Le JS onkeypress peut être tout ce que vous devez faire. Il n'y a pas besoin d'un changement global plus important. Cela est particulièrement vrai si vous n'êtes pas celui qui code l'application à partir de zéro et que vous avez été amené à réparer le site Web d'une autre personne sans la déchirer et la tester à nouveau.

2
garlicman

J'ai eu un problème similaire, où j'avais une grille avec "ajax textfields" (Yii CGridView) et juste un bouton d'envoi. Chaque fois que j'ai fait une recherche sur un champ de texte et que j'ai appuyé sur entrer le formulaire soumis. Je devais faire quelque chose avec le bouton car c’était le seul bouton commun entre les vues (modèle MVC). Tout ce que je devais faire était de retirer type="submit" et de mettre onclick="document.forms[0].submit()

2
StackUnder

Il y a déjà beaucoup de bonnes réponses ici, je veux juste contribuer quelque chose du point de vue de l'expérience utilisateur. Les contrôles de clavier dans les formulaires sont très importants.

La question est de savoir comment désactiver la soumission en appuyant sur la touche Enter. Pas comment ignorer Enter dans une application entière. Pensez donc à attacher le gestionnaire à un élément de formulaire, pas à la fenêtre.

La désactivation de Enter pour la soumission du formulaire doit toujours permettre les éléments suivants:

  1. Soumission de formulaire via Enter lorsque le bouton d'envoi est activé.
  2. Soumission de formulaire lorsque tous les champs sont renseignés.
  3. Interaction avec les boutons non soumis via Enter.

Ceci est juste normal mais il respecte les trois conditions.

$('form').on('keypress', function(e) {
  // Register keypress on buttons.
  $attr = $(e.target).attr('type);
  if ($attr === 'button' || $attr === 'submit') {
    return true;
  }

  // Ignore keypress if all fields are not populated.
  if (e.which === 13 && !fieldsArePopulated(this)) {
    return false;
  }
});
1
Solvitieg

ONLY BLOCK SUBMIT mais pas d'autres fonctionnalités importantes de la touche Entrée, telles que la création d'un nouveau paragraphe dans un <textarea>:

window.addEventListener('keydown', function(event) {
  //set default value for variable that will hold the status of keypress
  pressedEnter = false;

  //if user pressed enter, set the variable to true
  if (event.keyCode == 13)
    pressedEnter = true;

  //we want forms to disable submit for a tenth of a second only
  setTimeout(function() {
    pressedEnter = false;
  }, 100)

})

//find all forms
var forms = document.getElementsByTagName('form')

//loop through forms
for (i = 0; i < forms.length; i++) {
  //listen to submit event
  forms[i].addEventListener('submit', function(e) {
    //if user just pressed enter, stop the submit event
    if (pressedEnter == true) {
      updateLog('Form prevented from submit.')
      e.preventDefault();
      return false;
    }

    updateLog('Form submitted.')
  })
}

var log = document.getElementById('log')
updateLog = function(msg) {
  log.innerText = msg
}
input,
textarea {
  display: inline-block;
  margin-bottom: 1em;
  border: 1px solid #6f6f6f;
  padding: 5px;
  border-radius: 2px;
  width: 90%;
  font-size: 14px;
}

input[type=submit] {
  background: lightblue;
  color: #fff;
}
<form>
  <p>Sample textarea (try enter key):</p>
  <textarea rows="4">Hit enter, a new line will be added. But the form won't submit</textarea><br/>
  <p>Sample textfield (try enter key):</p>
  <input type="text" placeholder="" />
  <br/>
  <input type="submit" value="Save" />
  <h3 id="log"></h3>
</form>
1
mate.gwozdz

Ça marche pour moi

jQuery.each($("#your_form_id").find('input'), function(){
    $(this).bind('keypress keydown keyup', function(e){
       if(e.keyCode == 13) { e.preventDefault(); }
    });
});
0
Pjl

J'aimerais ajouter un peu de code CoffeeScript (non testé sur le terrain):

$ ->
    $(window).bind 'keypress', (event) ->
        if event.keyCode == 13
            unless {'TEXTAREA', 'SELECT'}[event.originalEvent.srcElement.tagName]
                event.preventDefault()

(J'espère que vous aimez le truc de Nice dans la clause less.)

0
edx

Quelque chose que je n’ai pas vu qui ait répondu ici: lorsque vous parcourez les éléments de la page, appuyez sur Enter Lorsque vous accédez au bouton de soumission, le gestionnaire onsubmit du formulaire est déclenché, mais il enregistre l'événement en tant que MouseEvent. Voici ma solution courte pour couvrir la plupart des bases:

Ce n'est pas une réponse liée à jQuery

HTML

<form onsubmit="return false;" method=post>
  <input type="text" /><br />
  <input type="button" onclick="this.form.submit()" value="submit via mouse or keyboard" />
  <input type="button" onclick="submitMouseOnly(event)" value="submit via mouse only" />
</form>

JavaScript

window.submitMouseOnly=function(evt){
    let allow=(evt instanceof MouseEvent) && evt.x>0 && evt.y>0 && evt.screenX > 0 && evt.screenY > 0;
    if(allow)(evt.tagName=='FORM'?evt.target:evt.target.form).submit();
}

Pour trouver un exemple de travail: https://jsfiddle.net/nemesarial/6rhogva2/

0
Nemesarial

Allez dans votre css et ajoutez-y cela bloquera automatiquement la soumission de votre formulaire tant que vous aurez soumis une entrée si vous ne le souhaitez plus, vous pouvez le supprimer ou taper activate et deactivate à la place.

 input:disabled {
        background: gainsboro;
      }
      input[value]:disabled {
        color: whitesmoke;
      }
0
Lars Gross

Dans mon cas spécifique, je devais empêcher ENTER de soumettre le formulaire et simuler le clic du bouton d'envoi. Cela est dû au fait que le bouton d'envoi comportait un gestionnaire de clics, car nous nous trouvions dans une fenêtre modale (ancien code hérité). En tout cas voici mes solutions de combo pour ce cas.

    $('input,select').keypress(function(event) {
        // detect ENTER key
        if (event.keyCode == 13) {
            // simulate submit button click
            $("#btn-submit").click();
            // stop form from submitting via ENTER key press
            event.preventDefault ? event.preventDefault() : event.returnValue = false;
        }
    });

Ce cas d'utilisation est particulièrement utile pour les personnes travaillant avec IE8.

0
Stone