1172 votes

Comment empêcher les boutons de soumettre les formulaires

Dans la page suivante, avec Firefox, le bouton de suppression soumet le formulaire, mais pas le bouton d'ajout.

Comment puis-je empêcher le remove de soumettre le formulaire ?

function addItem() {
  var v = $('form :hidden:last').attr('name');
  var n = /(.*)input/.exec(v);

  var newPrefix;
  if (n[1].length == 0) {
    newPrefix = '1';
  } else {
    newPrefix = parseInt(n[1]) + 1;
  }

  var oldElem = $('form tr:last');
  var newElem = oldElem.clone(true);
  var lastHidden = $('form :hidden:last');

  lastHidden.val(newPrefix);

  var pat = '=\"' + n[1] + 'input';

  newElem.html(newElem.html().replace(new RegExp(pat, 'g'), '=\"' + newPrefix + 'input'));
  newElem.appendTo('table');
  $('form :hidden:last').val('');
}

function removeItem() {
  var rows = $('form tr');
  if (rows.length > 2) {
    rows[rows.length - 1].html('');
    $('form :hidden:last').val('');
  } else {
    alert('Cannot remove any more rows');
  }
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<html>
<body>
    <form autocomplete="off" method="post" action="">
        <p>Title:<input type="text" /></p>
        <button onclick="addItem(); return false;">Add Item</button>
        <button onclick="removeItem(); return false;">Remove Last Item</button>
        <table>
            <th>Name</th>

            <tr>
                <td><input type="text" id="input1" name="input1" /></td>
                <td><input type="hidden" id="input2" name="input2" /></td>
            </tr>
        </table>
        <input id="submit" type="submit" name="submit" value="Submit">
    </form>
</body>

</html>

0 votes

Quelle réponse recommandez-vous, s'il vous plaît ?

2407voto

Metafaniel Points 2714

Vous utilisez un élément de bouton HTML5. Rappelez-vous la raison est que ce bouton a un comportement par défaut de soumettre, comme indiqué dans la spécification W3 comme vu ici : Bouton HTML5 du W3C

Vous devez donc spécifier son type explicitement :

<button type="button">Button</button>

afin de remplacer le type de soumission par défaut. Je veux juste souligner la raison pour laquelle cela se produit.

75 votes

Je tiens également à signaler qu'un élément HTML ayant un attribut type, dont l'un des types est bouton ne devrait pas avoir un type par défaut de soumettre . C'est tout simplement idiot, et une énorme erreur dans la spécification. J'utilise des boutons dans des formulaires tout le temps, et même si c'était un cas limite (ce qui n'est pas le cas), il serait toujours logique que le type par défaut soit submit.

12 votes

J'ai passé la majeure partie de la semaine à m'agacer du fait que mon application Electron "s'actualise" lorsque j'ouvre une modale à l'aide d'un bouton dans un formulaire. Cela se produisait une fois, puis l'application se comportait comme je l'attendais. Je n'avais absolument aucune idée de ce qui se passait. C'était ça ! Je n'ai aucun problème avec le fait que le type par défaut soit submit. Mais c'est un peu un piège, car il m'a fallu cinq ans pour l'apprendre.

9 votes

Grâce à votre référence, je viens d'apprendre qu'il existe un type=reset pour le formulaire. Génial !

651voto

Shog9 Points 82052

Définissez le type de vos boutons :

<button type="button" onclick="addItem(); return false;">Add Item</button>
<button type="button" onclick="removeItem(); return false;">Remove Last Item</button>

...qui les empêchera de déclencher une action de soumission lorsqu'une exception se produit dans le gestionnaire d'événements. Ensuite, corrigez votre removeItem() afin qu'elle ne déclenche pas d'exception :

function removeItem() {
  var rows = $('form tr');
  if ( rows.length > 2 ) {
    // change: work on filtered jQuery object
    rows.filter(":last").html('');
    $('form :hidden:last').val('');
  } else {
    alert('Cannot remove any more rows');
  }
}

Notez le changement : votre code d'origine extrayait un élément HTML de l'ensemble jQuery, puis essayait d'appeler une méthode jQuery sur cet élément - cela a déclenché une exception, ce qui a entraîné le comportement par défaut du bouton.

Pour info, il y a une autre façon de procéder... Connectez vos gestionnaires d'événements à l'aide de jQuery, et utilisez la balise preventDefault() sur la méthode de jQuery événement pour annuler d'emblée le comportement par défaut :

$(function() // execute once the DOM has loaded
{

  // wire up Add Item button click event
  $("#AddItem").click(function(event)
  {
    event.preventDefault(); // cancel default behavior

    //... rest of add logic
  });

  // wire up Remove Last Item button click event
  $("RemoveLastItem").click(function(event)
  {
    event.preventDefault(); // cancel default behavior

    //... rest of remove last logic
  });

});

...

<button type="button" id="AddItem" name="AddItem">Add Item</button>
<button type="button" id="RemoveLastItem" name="RemoveLastItem">Remove Last Item</button>

Cette technique permet de conserver toute la logique en un seul endroit, ce qui facilite le débogage... elle permet également de mettre en place une solution de repli en changeant la valeur de l'option type sur les boutons de retour à submit et traiter l'événement côté serveur - c'est ce que l'on appelle JavaScript discret .

5 votes

Type="button" ne fonctionne pas toujours dans Firefox pour moi. Si le js est assez compliqué, et qu'il y a une erreur, Firefox soumettra quand même le formulaire. C'est de la folie !

2 votes

@MatthewLock : Pas du tout - une erreur dans le script ferme simplement ce bloc de code, et l'action se poursuit comme d'habitude. Essayez d'invoquer les méthodes d'événement jQuery e.preventDefault() et/ou e.stopPropgation() comme premières lignes de la méthode. Voir stackoverflow.com/questions/2017755/ pour en savoir plus

8 votes

Type=bouton ne devrait jamais soumettre le formulaire, peu importe ce qu'il faut faire.

38voto

z666zz666z Points 659

Il y a quelque temps, j'ai eu besoin de quelque chose de très similaire... et je l'ai eu.

Donc, ce que j'ai mis ici est comment je fais les trucs pour avoir un formulaire capable d'être soumis par JavaScript sans aucune validation et exécuter la validation seulement quand l'utilisateur appuie sur un bouton (typiquement un bouton d'envoi).

Pour l'exemple, je vais utiliser un formulaire minimal, avec seulement deux champs et un bouton d'envoi.

Rappelez-vous ce que l'on veut : A partir de JavaScript, il doit pouvoir être soumis sans aucune vérification. Cependant, si l'utilisateur appuie sur un tel bouton, la validation doit être faite et le formulaire envoyé seulement s'il passe la validation.

Normalement, tout devrait commencer à peu près comme ceci (j'ai enlevé tous les éléments supplémentaires qui ne sont pas importants) :

<form method="post" id="theFormID" name="theFormID" action="">
   <input type="text" id="Field1" name="Field1" />
   <input type="text" id="Field2" name="Field2" />
   <input type="submit" value="Send" onclick="JavaScript:return Validator();" />
</form>

Voyez comment la balise de formulaire n'a pas onsubmit="..." (rappelez-vous que c'était une condition pour ne pas l'avoir).

Le problème est que le formulaire est toujours soumis, peu importe si onclick renvoie à true ou false .

Si je change type="submit" pour type="button" Il semble que cela fonctionne, mais ce n'est pas le cas. Il n'envoie jamais le formulaire, mais cela peut être fait facilement.

Alors finalement, j'ai utilisé ceci :

<form method="post" id="theFormID" name="theFormID" action="">
   <input type="text" id="Field1" name="Field1" />
   <input type="text" id="Field2" name="Field2" />
   <input type="button" value="Send" onclick="JavaScript:return Validator();" />
</form>

Et sur function Validatorreturn True; est, j'ajoute également une phrase JavaScript submit, quelque chose de similaire à ceci :

function Validator(){
   //  ...bla bla bla... the checks
   if(                              ){
      document.getElementById('theFormID').submit();
      return(true);
   }else{
      return(false);
   }
}

Le site id="" est juste pour JavaScript getElementById le name="" c'est juste pour qu'il apparaisse sur les données POST.

De cette manière, cela fonctionne comme je le souhaite.

Je mets ça juste pour les gens qui n'ont pas besoin onsubmit sur le formulaire, mais faites une validation quand un bouton est pressé par l'utilisateur.

Pourquoi n'ai-je pas besoin de onsubmit sur le tag du formulaire ? Facile, sur d'autres parties JavaScript je dois effectuer un submit mais je ne veux pas qu'il y ait de validation.

La raison : si l'utilisateur est celui qui effectue l'envoi, je veux et j'ai besoin que la validation soit effectuée, mais si c'est JavaScript, je dois parfois effectuer l'envoi alors que ces validations l'éviteraient.

Cela peut sembler étrange, mais pas quand on pense par exemple : sur un Login ... avec quelques restrictions ... comme ne pas autoriser l'utilisation de sessions PHP et aucun cookie n'est autorisé !

Tout lien doit donc être converti en un tel formulaire de soumission, afin que les données de connexion ne soient pas perdues. Lorsqu'aucune connexion n'est encore effectuée, le lien doit également fonctionner. Aucune validation ne doit donc être effectuée sur les liens. Mais je veux présenter un message à l'utilisateur si celui-ci n'a pas saisi les deux champs, utilisateur et pass. Donc si l'un d'eux est manquant, le formulaire ne doit pas être envoyé ! voilà le problème.

Voir le problème : le formulaire ne doit pas être envoyé quand un champ est vide seulement si l'utilisateur a appuyé sur un bouton, si c'est un code JavaScript il doit pouvoir être envoyé.

Si je fais le travail sur onsubmit sur la balise du formulaire, j'aurais besoin de savoir si c'est l'utilisateur ou un autre JavaScript. Comme aucun paramètre ne peut être passé, ce n'est pas possible directement, donc certaines personnes ajoutent une variable pour dire si la validation doit être faite ou non. La première chose à faire dans la fonction de validation est de vérifier la valeur de cette variable, etc... Trop compliqué et le code ne dit pas ce que l'on veut vraiment.

La solution est donc de ne pas avoir de onsubmit sur la balise du formulaire. En revanche, il faut le placer là où il est vraiment nécessaire, sur le bouton.

De l'autre côté, pourquoi mettre le code onsubmit puisque conceptuellement je ne veux pas de validation onsubmit. Je veux vraiment une validation par bouton.

Non seulement le code est plus clair, mais il est là où il doit être. Rappelez-vous ceci : - Je ne veux pas que JavaScript valide le formulaire (cela doit toujours être fait par PHP du côté du serveur). - Je veux montrer à l'utilisateur un message indiquant que tous les champs ne doivent pas être vides, ce qui nécessite JavaScript (côté client).

Alors pourquoi certaines personnes (pensent ou me disent) que cela doit être fait sur une validation onsumbit ? Non, conceptuellement, je ne fais pas de validation onsumbit du côté client. Je fais juste quelque chose quand un bouton est pressé, alors pourquoi ne pas simplement laisser cela être implémenté ?

Eh bien, ce code et ce style font parfaitement l'affaire. Sur tous les JavaScript dont j'ai besoin pour envoyer le formulaire, je mets simplement :

document.getElementById('theFormID').action='./GoToThisPage.php'; // Where to go
document.getElementById('theFormID').submit(); // Send POST data and go there

Et qui saute la validation quand je n'en ai pas besoin. Il envoie simplement le formulaire et charge une autre page, etc.

Mais si l'utilisateur clique sur le bouton d'envoi (alias type="button" pas type="submit" ) la validation est faite avant de laisser le formulaire être soumis et si non valide non envoyé.

J'espère que cela aidera d'autres personnes à ne pas essayer un code long et compliqué. Il suffit de ne pas utiliser onsubmit si ce n'est pas nécessaire, et utiliser onclick . Mais n'oubliez pas de changer type="submit" à type="button" et n'oubliez pas de faire le submit() par JavaScript.

31voto

poundifdef Points 6005

Je suis d'accord avec Shog9, mais je pourrais plutôt utiliser :

<input type = "button" onClick="addItem(); return false;" value="Add Item" />

Selon w3schools le <button> a un comportement différent selon les navigateurs.

22voto

Shiala Points 78

$("form").submit(function () { return false; }); qui empêchera le bouton de se soumettre ou vous pouvez simplement changer le type de bouton en "bouton". <input type="button"/> au lieu de <input type="submit"/> Ce qui ne fonctionnera que si ce bouton n'est pas le seul bouton de ce formulaire.

2 votes

Ceci est pour jQuery, un équivalent en Javascript est : myform.onsubmit = function() {return false} ... aussi, même si vous enlevez le bouton submit, le formulaire pourrait aussi être soumis en appuyant sur enter depuis un autre champ du formulaire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X