Comment empêcher les boutons de soumettre des formulaires

917

Dans la page suivante, avec Firefox, le bouton Supprimer soumet le formulaire, mais pas le bouton Ajouter. Comment empêcher le bouton Supprimer de soumettre le formulaire?

<html>

<head>
    <script type="text/javascript" src="jquery-1.3.2.min.js"></script>
    <script type="text/javascript">
        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>
</head>

<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>
Khanpo
la source
quelle réponse recommandez-vous s'il vous plaît?
sanepete

Réponses:

1799

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

Vous devez donc spécifier explicitement son type:

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

=)

Metafaniel
la source
17
Je tiens également à souligner qu'un élément HTML ayant un attribut type, dont l'un des types est button , ne devrait pas f # $ 'n avoir un type de soumission par défaut . C'est tout simplement idiot, et une énorme erreur dans la spécification. J'utilise des boutons dans les formulaires tout le temps, et même s'il s'agissait d'un cas de bord (ce qui n'est pas le cas), il serait toujours judicieux de soumettre le type par défaut.
dudewad
3
🤯 J'ai passé la majeure partie de cette semaine ennuyé que mon application Electron "rafraîchie" lorsque j'ouvre un modal en utilisant un bouton dans un formulaire. Cela arriverait une fois, puis l'application se comporterait comme je m'y attendais. Je n'avais absolument aucune idée de ce qui se passait. C'était ça! Je n'ai aucun problème avec le type par défaut soumis. Cela semble un peu fou, car cela m'a pris cinq ans pour en savoir plus.
freethebees
4
Grâce à votre référence, je viens d'apprendre qu'il y a un type = reset pour le formulaire. Impressionnant!
Duong Nguyen
602

Définissez le type sur vos boutons:

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

... cela 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()fonction 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 a extrait un élément HTML de l'ensemble jQuery, puis a essayé d'appeler une méthode jQuery dessus - cela a généré une exception, entraînant le comportement par défaut du bouton.

FWIW, il y a une autre façon de procéder avec cela ... Câblez vos gestionnaires d'événements à l'aide de jQuery et utilisez la méthode preventDefault () sur l' objet événement de jQuery pour annuler le comportement par défaut à l'avance:

$(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 conserve toute votre logique au même endroit, ce qui facilite le débogage ... elle vous permet également d'implémenter une solution de repli en changeant typeles boutons sur submitet en gérant l'événement côté serveur - cela est connu comme discret JavaScript .

Shog9
la source
4
type = "bouton" ne fonctionne pas toujours dans Firefox pour moi. Si le js est suffisamment compliqué et qu'il y a une erreur, Firefox soumettra le formulaire de toute façon. Folie!
Matthew Lock
1
@MatthewLock: À peine - une erreur dans le script arrête simplement ce bloc de code, et l'action se déroule comme d'habitude. Essayez d'appeler 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
brichins
8
type = button ne doit jamais envoyer le formulaire, quoi qu'il
arrive
1
return falseest si important. parfois même l'utiliser pour le bouton soumettre ( onclick
Jamie
7
Je pense que le HTML est étrange ici. Il doit être de type = "bouton" par défaut, ne pas soumettre. Il m'est toujours inattendu de voir cette soumission par défaut. C'est l'exception.
httpete
31

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

Donc, ce que je mets ici, c'est comment je fais les astuces pour avoir un formulaire pouvant être soumis par JavaScript sans aucune validation et exécuter la validation uniquement lorsque l'utilisateur appuie sur un bouton (généralement un bouton d'envoi).

Pour l'exemple, j'utiliserai un formulaire minimal, uniquement avec deux champs et un bouton de soumission.

Rappelez-vous ce qui est recherché: à 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 effectuée et le formulaire envoyé uniquement s'il réussit la validation.

Normalement, tout commencerait à partir de quelque chose près de cela (j'ai supprimé tous les trucs supplémentaires sans importance):

<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, qu'il onclickretourne trueou false.

Si je change type="submit"pour type="button", cela semble fonctionner mais ne fonctionne pas. Il n'envoie jamais le formulaire, mais cela peut se faire facilement.

J'ai finalement 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 Validator, où return True;est, j'ajoute également une phrase de soumission JavaScript, quelque chose de similaire à ceci:

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

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

De cette façon, cela fonctionne comme j'ai besoin.

Je mets cela uniquement pour les personnes qui n'ont besoin d'aucune onsubmitfonction sur le formulaire, mais je fais une validation lorsqu'un utilisateur appuie sur un bouton.

Pourquoi je n'ai besoin d'aucune soumission sur la balise de formulaire? Facile, sur d'autres parties JavaScript, je dois effectuer une soumission mais je ne veux pas qu'il y ait de validation.

La raison: si l'utilisateur est celui qui effectue la soumission, je veux et que la validation soit effectuée, mais s'il s'agit de JavaScript, je dois parfois effectuer la soumission alors que de telles validations l'éviteraient.

Cela peut sembler étrange, mais pas en pensant par exemple: à une connexion ... avec quelques restrictions ... comme ne pas autoriser les sessions PHP et les cookies ne sont pas autorisés!

Donc, tout lien doit être converti en un tel formulaire, afin que les données de connexion ne soient pas perdues. Lorsqu'aucune connexion n'est encore effectuée, cela doit également fonctionner. Aucune validation ne doit donc être effectuée sur les liens. Mais je veux présenter un message à l'utilisateur si l'utilisateur n'a pas entré les deux champs, user et pass. Donc, s'il en manque un, le formulaire ne doit pas être envoyé! il y a le problème.

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

Si je fais le travail sur onsubmitla balise de formulaire, j'aurais besoin de savoir s'il s'agit de l'utilisateur ou d'un autre JavaScript. Puisqu'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 effectuée ou non. La première chose sur 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 n'est donc pas d'avoir onsubmit sur la balise form. Insead le mettre là où il est vraiment nécessaire, sur le bouton.

Pour l'autre côté, pourquoi mettre du code onsubmit puisque conceptuellement je ne veux pas de validation onsubmit. Je veux vraiment la validation des boutons.

Non seulement le code est plus clair, il est là où il doit être. N'oubliez pas ceci: - Je ne veux pas que JavaScript valide le formulaire (cela doit toujours être fait par PHP côté serveur) - Je veux montrer à l'utilisateur un message disant que tous les champs ne doivent pas être vides, qui ont besoin de JavaScript (client côté)

Alors pourquoi certaines personnes (pensez ou dites-moi) cela doit être fait sur une validation onsumbit? Non, conceptuellement, je ne fais pas de validation onsumbit côté client. Je fais juste quelque chose sur un bouton pressé, alors pourquoi ne pas simplement laisser cela être mis en œuvre?

Eh bien, ce code et ce style font parfaitement l'affaire. Sur tout JavaScript dont j'ai besoin pour envoyer le formulaire que je viens de mettre:

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

Et cela saute la validation lorsque je n'en ai pas besoin. Il envoie simplement le formulaire et charge une page différente, etc.

Mais si l'utilisateur clique sur le bouton Soumettre (alias type="button"non type="submit"), la validation est effectuée avant de laisser le formulaire soumis et s'il n'est pas valide, il n'est pas envoyé.

J'espère que cela aide les autres à ne pas essayer de code long et compliqué. Ne l'utilisez pas onsubmitsi vous n'en avez pas besoin et utilisez-le onclick. Mais n'oubliez pas de passer type="submit"à type="button"et s'il vous plaît n'oubliez pas de le faire submit()par JavaScript.

z666zz666z
la source
28

Je suis d'accord avec Shog9, bien que je puisse utiliser à la place:

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

Selon w3schools , la <button>balise a un comportement différent sur différents navigateurs.

poundifdef
la source
18

Supposons que votre formulaire HTML comporte id="form_id"

<form id="form_id">
<!--your HTML code-->
</form>

Ajoutez cet extrait jQuery à votre code pour voir le résultat,

$("#form_id").submit(function(){
  return false;
});
Prateek Joshi
la source
18

Vous pouvez simplement obtenir la référence de vos boutons en utilisant jQuery, et empêcher sa propagation comme ci-dessous:

 $(document).ready(function () {
    $('#BUTTON_ID').click(function(e) {

            e.preventDefault();
            e.stopPropagation();
            e.stopImmediatePropagation();

            return false;
    });});
Ata Iravani
la source
2
e.preventDefault(); e.stopPropagation();suffit pour que les choses fonctionnent. e.stopImmediatePropagation()cela génère une erreur de méthode non définie dans Chrome.
Subroto
14

$("form").submit(function () { return false; }); cela 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"/> Qui ne fonctionnera que si ce bouton n'est pas le seul bouton de ce formulaire.

Shiala
la source
2
C'est pour jQuery, un équivalent en Javascript est: myform.onsubmit = function () {return false} ... aussi, même si vous supprimez le bouton soumettre, le formulaire peut également être soumis en appuyant sur Entrée dans un autre champ de formulaire.
Synexis
10

Il s'agit d'une erreur html5 comme cela a été dit, vous pouvez toujours avoir le bouton en tant que soumission (si vous souhaitez couvrir à la fois les utilisateurs javascript et non javascript) en l'utilisant comme:

     <button type="submit" onclick="return false"> Register </button>

De cette façon, vous annulerez la soumission, mais vous ferez tout ce que vous faites dans les fonctions jquery ou javascript et vous effectuerez la soumission pour les utilisateurs qui ne disposent pas de javascript.

sagits
la source
8

Je suis sûr que sur FF le

removeItem 

la fonction rencontre une erreur JavaScript, cela ne s'est pas produit sur IE

Lorsque l'erreur javascript apparaît, le code "return false" ne s'exécute pas, ce qui rend la page à poster

Alin Vasile
la source
8

Le retour false empêche le comportement par défaut. mais le retour faux rompt le bouillonnement d'événements de clic supplémentaires. Cela signifie que s'il existe d'autres liaisons de clic après l'appel de cette fonction, les autres ne sont pas prises en compte.

 <button id="btnSubmit" type="button">PostData</button>
 <Script> $("#btnSubmit").click(function(){
   // do stuff
   return false;
}); </Script>

Ou simplement vous pouvez mettre comme ça

 <button type="submit" onclick="return false"> PostData</button>
Sunil Dhappadhule
la source
7

Ajoutez simplement e.preventDefault();votre méthode pour empêcher votre page de soumettre des formulaires.

function myFunc(e){
       e.preventDefault();
}

Selon les documents Web MDN

La méthode preventDefault () de l'interface Event indique à l'agent utilisateur que si l'événement n'est pas traité explicitement, son action par défaut ne doit pas être prise en compte comme elle le serait normalement. L'événement continue de se propager comme d'habitude, sauf si l'un de ses auditeurs appelle stopPropagation ()ou stopImmediatePropagation (), l'un des deux arrête la propagation.

Mselmi Ali
la source
6

Réglez votre bouton de manière normale et utilisez event.preventDefault comme ..

   <button onclick="myFunc(e)"> Remove </button>  
   ...
   ...

   In function...

   function myFunc(e){
       e.preventDefault();
   }
Vishal
la source
4
return false;

Vous pouvez retourner false à la fin de la fonction ou après l'appel de fonction.

Tant que c'est la dernière chose qui se produit, le formulaire ne sera pas envoyé.

WonderWorker
la source
2

Voici une approche simple:

$('.mybutton').click(function(){

    /* Perform some button action ... */
    alert("I don't like it when you press my button!");

    /* Then, the most important part ... */
    return false;

});
axiom82
la source
1

L'exemple de code suivant vous montre comment empêcher le clic du bouton de soumettre le formulaire.

Vous pouvez essayer mon exemple de code:

 <form autocomplete="off" method="post" action="">
   <p>Title:
     <input type="text" />
   </p>
   <input type="button" onclick="addItem()" value="Add Item">
   <input type="button" onclick="removeItem()" value="Remove Last Item">
   <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>
<script language="javascript">
function addItem() {
return false;
}

function removeItem() {
return false;
}
</script>
Le KNVB
la source
0

Je ne suis pas en mesure de tester cela pour le moment, mais je pense que vous pourriez utiliser la méthode preventDefault de jQuery .

Tyler Rash
la source
0

La fonction removeItem contient en fait une erreur, ce qui fait que le bouton du formulaire fait son comportement par défaut (soumission du formulaire). La console d'erreur javascript donnera généralement un pointeur dans ce cas.

Découvrez la fonction removeItem dans la partie javascript:

La ligne:

rows[rows.length-1].html('');

ne fonctionne pas. Essayez plutôt ceci:

rows.eq(rows.length-1).html('');
ylebre
la source