Question

J'ai un formulaire qui prend un peu de temps à traiter par le serveur.Je dois m'assurer que l'utilisateur attend et ne tente pas de soumettre à nouveau le formulaire en cliquant à nouveau sur le bouton.J'ai essayé d'utiliser le code jQuery suivant :

<script type="text/javascript">
$(document).ready(function() {
    $("form#my_form").submit(function() {
        $('input').attr('disabled', 'disabled');
        $('a').attr('disabled', 'disabled');
        return true;
    });
});
</script>

Lorsque j'essaie cela dans Firefox, tout est désactivé mais le formulaire n'est soumis avec aucune des données POST qu'il est censé inclure.Je ne peux pas utiliser jQuery pour soumettre le formulaire car j'ai besoin que le bouton soit soumis avec le formulaire car il existe plusieurs boutons de soumission et je détermine lequel a été utilisé par lequel la valeur est incluse dans le POST.J'ai besoin que le formulaire soit soumis tel qu'il est habituellement et je dois tout désactiver juste après que cela se produise.

Merci!

Était-ce utile?

La solution

Mise à jour en 2018 : Je viens de recevoir quelques points pour cette vieille réponse, et je voulais juste ajouter que la meilleure solution serait de faire la idempotent opération de telle sorte que double soumissions sont inoffensifs.

Par exemple, si la forme crée un ordre, mettre un identifiant unique sous la forme. La première fois que le serveur voit une demande de création d'une commande avec cet identifiant, il faut le créer et de répondre « succès ». Les présentations subséquentes devraient également répondre « succès » (dans le cas où le client n'a pas obtenu la première réponse), mais il ne faut rien de changement.

Doublons doit être détectée par un contrôle unique dans la base de données pour éviter les conditions de course.


Je pense que votre problème est cette ligne:

$('input').attr('disabled','disabled');

Vous désactiver toutes les entrées, y compris, je suppose, ceux dont les données du formulaire est censé soumettre.

Pour désactiver simplement le bouton d'envoi (s), vous pourrait faire ceci:

$('button[type=submit], input[type=submit]').prop('disabled',true);

Cependant, je ne pense pas que IE soumettre le formulaire si même ces boutons sont désactivés. Je suggère une approche différente.

Un plugin jQuery pour résoudre

Nous avons résolu ce problème avec le code suivant. L'astuce ici utilise le data() jQuery pour marquer la forme comme cela a déjà soumis ou non. De cette façon, nous n'avons pas jouer avec les boutons submit qui Freaks IE sur.

// jQuery plugin to prevent double submission of forms
jQuery.fn.preventDoubleSubmission = function() {
  $(this).on('submit',function(e){
    var $form = $(this);

    if ($form.data('submitted') === true) {
      // Previously submitted - don't submit again
      e.preventDefault();
    } else {
      // Mark it so that the next submit can be ignored
      $form.data('submitted', true);
    }
  });

  // Keep chainability
  return this;
};

Utilisez comme ceci:

$('form').preventDoubleSubmission();

S'il existe des formes AJAX que devrait être autorisé à présenter plusieurs fois par chargement de la page, vous pouvez leur donner une classe indiquant que, puis les exclure de votre sélection comme ceci:

$('form:not(.js-allow-double-submission)').preventDoubleSubmission();

Autres conseils

approche de timing est mauvais - comment savez-vous combien de temps l'action prendra sur le navigateur du client

Comment faire

$('form').submit(function(){
  $(this).find(':submit').attr('disabled','disabled');
});

Lorsque le formulaire est soumis, il désactive tous les boutons de soumission à l'intérieur.

Rappelez-vous, dans Firefox lorsque vous désactivez un bouton se rappeler cet état quand vous revenez dans l'histoire. Pour éviter que vous devez activer les boutons sur la charge de page, par exemple.

Je pense que la réponse de Nathan Long est le chemin à parcourir. Pour moi, je me sers de validation côté client, donc je viens d'ajouter une condition que la forme soit valide.

EDIT :. Si ce n'est pas ajouté, l'utilisateur ne sera jamais en mesure de soumettre le formulaire si la validation du côté client rencontre une erreur

        // jQuery plugin to prevent double submission of forms
        jQuery.fn.preventDoubleSubmission = function () {
            $(this).on('submit', function (e) {
                var $form = $(this);

                if ($form.data('submitted') === true) {
                    // Previously submitted - don't submit again
                    alert('Form already submitted. Please wait.');
                    e.preventDefault();
                } else {
                    // Mark it so that the next submit can be ignored
                    // ADDED requirement that form be valid
                    if($form.valid()) {
                        $form.data('submitted', true);
                    }
                }
            });

            // Keep chainability
            return this;
        };

event.timeStamp ne fonctionne pas dans Firefox. De retour faux est non standard, vous devez appeler event.preventDefault(). Et pendant que nous y sommes, toujours utiliser des accolades avec une construction témoin .

Pour résumer toutes les réponses précédentes, voici un plug-in qui fait le travail et travaille cross-browser.

jQuery.fn.preventDoubleSubmission = function() {

    var last_clicked, time_since_clicked;

    jQuery(this).bind('submit', function(event) {

        if(last_clicked) {
            time_since_clicked = jQuery.now() - last_clicked;
        }

        last_clicked = jQuery.now();

        if(time_since_clicked < 2000) {
            // Blocking form submit because it was too soon after the last submit.
            event.preventDefault();
        }

        return true;
    });
};

Pour adresse Kern3l, les travaux de la méthode de synchronisation pour moi tout simplement parce que nous essayons d'arrêter un double-clic sur le bouton soumettre. Si vous avez un temps de réponse très longue à une présentation, je vous recommande de remplacer le bouton soumettre ou sous forme d'une fileuse.

bloquer complètement les soumissions ultérieures de la forme, comme la plupart des exemples ci-dessus ne, a un mauvais effet secondaire: s'il y a une défaillance du réseau et ils veulent essayer de soumettre à nouveau, ils seraient incapables de le faire et se perdre les changements qu'ils ont fait. Ce serait certainement faire un utilisateur en colère.

S'il vous plaît, consultez -jquery plug-in safeform .

Exemple d'utilisation:

$('.safeform').safeform({
    timeout: 5000,  // disable next submission for 5 sec
    submit: function() {
        // You can put validation and ajax stuff here...

        // When done no need to wait for timeout, re-enable the form ASAP
        $(this).safeform('complete');
        return false;
    }
});

... Mais le formulaire n'est soumis avec aucune des données de poste qu'il est censé inclure.

Correct.Les noms/valeurs des éléments de formulaire désactivés ne seront pas envoyés au serveur.Vous devriez les définir comme lecture seulement éléments.

De plus, les ancres ne peuvent pas être désactivées de cette façon.Vous devrez soit supprimer leurs HREF (non recommandé), soit empêcher leur comportement par défaut (meilleure façon), par exemple :

<script type="text/javascript">
$(document).ready(function(){
    $("form#my_form").submit(function(){
      $('input').attr('readonly', true);
      $('input[type=submit]').attr("disabled", "disabled");
      $('a').unbind("click").click(function(e) {
          e.preventDefault();
          // or return false;
      });
    });
</script>

Il est possible d'améliorer Nathan Long . Vous pouvez remplacer la logique pour la détection de la forme déjà présenté avec celui-ci:

var lastTime = $(this).data("lastSubmitTime");
if (lastTime && typeof lastTime === "object") {
    var now = new Date();
    if ((now - lastTime) > 2000) // 2000ms
        return true;
    else
        return false;
}
$(this).data("lastSubmitTime", new Date());
return true; // or do an ajax call or smth else

Code de Nathan, mais pour le plugin jQuery Valider

Si vous arrive d'utiliser jQuery Validation plugin, ils ont déjà mis en œuvre soumettre gestionnaire, et dans ce cas, il n'y a aucune raison de mettre en œuvre plus d'un. Le code:

jQuery.validator.setDefaults({
  submitHandler: function(form){
    // Prevent double submit
    if($(form).data('submitted')===true){
      // Previously submitted - don't submit again
      return false;
    } else {
      // Mark form as 'submitted' so that the next submit can be ignored
      $(form).data('submitted', true);
      return true;
    }
  }
});

Vous pouvez facilement étendre dans le } else { bloc aux entrées désactiver et / ou le bouton soumettre.

Vive

Je fini par utiliser les idées de ce post pour arriver à une solution qui est assez similaire à la version AtZako.

 jQuery.fn.preventDoubleSubmission = function() {

    var last_clicked, time_since_clicked;

    $(this).bind('submit', function(event){

    if(last_clicked) 
      time_since_clicked = event.timeStamp - last_clicked;

    last_clicked = event.timeStamp;

    if(time_since_clicked < 2000)
      return false;

    return true;
  });   
};

En utilisant comme ceci:

$('#my-form').preventDoubleSubmission();

Je trouve que les solutions qui ne comprennent pas une sorte de délai d'attente mais juste soumission ou handicapés éléments de formulaire handicapés causé des problèmes, car une fois le lock-out est déclenchée, vous ne pouvez pas soumettre à nouveau jusqu'à ce que vous actualisez la page. Cela provoque des problèmes pour moi de faire des choses ajax.

Cela peut probablement être enjolivée un peu comme pas de fantaisie.

Si vous utilisez AJAX pour afficher une forme, ensemble async: false devrait empêcher d'autres avant la soumet forme Clairs:

$("#form").submit(function(){
    var one = $("#one").val();
    var two = $("#two").val();
    $.ajax({
      type: "POST",
      async: false,  // <------ Will complete submit before allowing further action
      url: "process.php",
      data: "one="+one+"&two="+two+"&add=true",
      success: function(result){
        console.log(result);
        // do something with result
      },
      error: function(){alert('Error!')}
    });
    return false;
   }
});

solution modifiée de Nathan un peu pour Bootstrap 3. Cela définira un texte de chargement sur le bouton soumettre. En outre, il expire au bout de 30 secondes et laisser la forme à nouveau soumis.

jQuery.fn.preventDoubleSubmission = function() {
  $('input[type="submit"]').data('loading-text', 'Loading...');

  $(this).on('submit',function(e){
    var $form = $(this);

    $('input[type="submit"]', $form).button('loading');

    if ($form.data('submitted') === true) {
      // Previously submitted - don't submit again
      e.preventDefault();
    } else {
      // Mark it so that the next submit can be ignored
      $form.data('submitted', true);
      $form.setFormTimeout();
    }
  });

  // Keep chainability
  return this;
};

jQuery.fn.setFormTimeout = function() {
  var $form = $(this);
  setTimeout(function() {
    $('input[type="submit"]', $form).button('reset');
    alert('Form failed to submit within 30 seconds');
  }, 30000);
};

Utilisez deux boutons de soumission.

<input id="sub" name="sub" type="submit" value="OK, Save">
<input id="sub2" name="sub2" type="submit" value="Hidden Submit" style="display:none">

Et jQuery:

$("#sub").click(function(){
  $(this).val("Please wait..");
  $(this).attr("disabled","disabled");
  $("#sub2").click();
});

J'ai eu des problèmes similaires et ma solution (s) sont les suivants.

Si vous n'avez pas la méthode de validation côté client, vous pouvez simplement utiliser une jquery () comme indiqué ici.

http://api.jquery.com/one/

Cela désactive le gestionnaire après son été invoqué.

$("#mysavebuttonid").on("click", function () {
  $('form').submit();
});

Si vous faites la validation du côté client que je faisais alors son un peu plus délicat. L'exemple ci-dessus ne vous laissera pas soumettre à nouveau après validation a échoué. Essayez cette approche à la place

$("#mysavebuttonid").on("click", function (event) {
  $('form').submit();
  if (boolFormPassedClientSideValidation) {
        //form has passed client side validation and is going to be saved
        //now disable this button from future presses
        $(this).off(event);
   }
});

Voici comment je le fais:

$(document).ready(function () {
  $('.class_name').click(function () {
    $(this).parent().append('<img src="data:image/gif;base64,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" />');
    $(this).hide();
  });
});

crédits: https://github.com/phpawy/jquery-submit-once

Utilisez compteur simple sur soumettre.

    var submitCounter = 0;
    function monitor() {
        submitCounter++;
        if (submitCounter < 2) {
            console.log('Submitted. Attempt: ' + submitCounter);
            return true;
        }
        console.log('Not Submitted. Attempt: ' + submitCounter);
        return false;
    }

Et la fonction monitor() d'appel sur soumettre le formulaire.

    <form action="/someAction.go" onsubmit="return monitor();" method="POST">
        ....
        <input type="submit" value="Save Data">
    </form>

ce code affiche le chargement sur l'étiquette du bouton, et le bouton SET pour

état de désactivation, puis après le traitement, réactivez et revenir en arrière le texte du bouton d'origine **

$(function () {

    $(".btn-Loading").each(function (idx, elm) {
        $(elm).click(function () {
            //do processing
            if ($(".input-validation-error").length > 0)
                return;
            $(this).attr("label", $(this).text()).text("loading ....");
            $(this).delay(1000).animate({ disabled: true }, 1000, function () {
                //original event call
                $.when($(elm).delay(1000).one("click")).done(function () {
                    $(this).animate({ disabled: false }, 1000, function () {
                        $(this).text($(this).attr("label"));
                    })
                });
                //processing finalized
            });
        });
    });
    // and fire it after definition
}

);

Ma solution:

// jQuery plugin to prevent double submission of forms
$.fn.preventDoubleSubmission = function () {
    var $form = $(this);

    $form.find('[type="submit"]').click(function () {
        $(this).prop('disabled', true);
        $form.submit();
    });

    // Keep chainability
    return this;
};

Modifier le bouton Soumettre :

<input id="submitButtonId" type="submit" value="Delete" />

Avec bouton normal :

<input id="submitButtonId" type="button" value="Delete" />

Utilisez ensuite la fonction clic :

$("#submitButtonId").click(function () {
        $('#submitButtonId').prop('disabled', true);
        $('#myForm').submit();
    });

Et n'oubliez pas de réactiver le bouton lorsque cela est nécessaire :

$('#submitButtonId').prop('disabled', false);

Je ne peux pas croire que le bon vieux truc façonné css de pointer-events: aucun n'a pas encore été mentionnés. J'ai eu le même problème en ajoutant un attribut désactivé, mais cela ne posterai pas. Essayez ci-dessous et le remplacer #SubmitButton avec l'ID de votre bouton Envoyer.

$(document).on('click', '#SubmitButton', function () {
    $(this).css('pointer-events', 'none');
})

Pourquoi ne pas simplement cela - cela soumettre le formulaire, mais aussi désactiver le bouton soumission,

   $('#myForm').on('submit', function(e) {
       var clickedSubmit = $(this).find('input[type=submit]:focus');
       $(clickedSubmit).prop('disabled', true);
   });

En outre, si vous utilisez jQuery Valider, vous pouvez mettre ces deux lignes sous if ($('#myForm').valid()).

Vous pouvez arrêter la seconde soumettre par cette

$("form").submit(function() {
        // submit more than once return false
        $(this).submit(function() {
            return false;
        });
        // submit once return true
        return true; // or do what you want to do
    });
});

Je résolu un problème très similaire en utilisant:

$("#my_form").submit(function(){
    $('input[type=submit]').click(function(event){
        event.preventDefault();
    });
});
scroll top