Frage

Ich habe ein Formular, das dauert eine Weile, um den server zu verarbeiten.Ich brauche, um sicherzustellen, dass der Benutzer wartet, und Sie versucht nicht, um Sie erneut das Formular, indem Sie die Taste erneut.Ich habe versucht, mit dem folgenden jQuery-code:

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

Wenn ich versuche diese in Firefox wird alles deaktiviert, aber das Formular wird nicht gesendet werden, mit jeder von den POST-Daten, die es enthalten sollte.Ich kann nicht verwenden Sie jQuery, um das Formular abschicken, weil ich brauche die Schaltfläche, um eingereicht werden, mit der form, wie es mehrere submit-buttons, die ich bestimmen, welche verwendet wurde, durch die man den Wert in der POST enthalten.Muss ich das Formular eingereicht werden, wie es normalerweise ist und ich brauche, um zu deaktivieren Sie alles, was direkt danach passiert.

Vielen Dank!

War es hilfreich?

Lösung

Update im Jahr 2018 : Ich habe ein paar Punkte für diese alte Antwort, und wollte nur hinzufügen, dass die am besten Lösung wäre, um den Vorgang idempotent, so dass doppelten Einreichungen sind harmlos.

Zum Beispiel, wenn das Formular einen Auftrag erstellt, setzen Sie eine eindeutige ID in das Formular ein. Das erste Mal, wenn der Server eine Auftragserstellung Anfrage mit dieser ID sieht, sollte sie es und reagiert „Erfolg“ erstellen. Nachreichungen sollte auch respond „Erfolg“ (im Falle hat der Kunde nicht die erste Antwort erhalten), aber sollte sich nicht ändern nichts.

Dubletten sollte über eine Einzigartigkeit Prüfung in der Datenbank zu verhindern Rennbedingungen festgestellt werden.


Ich denke, dass Ihr Problem ist diese Linie:

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

Sie deaktivieren alle Eingänge, einschließlich, denke ich würde, diejenigen, deren Daten die Form soll einzureichen.

So deaktivieren Sie einfach den Submit-Button (s), Sie könnte Sie folgendermaßen vor:

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

Aber ich glaube nicht, IE wird das Formular selbst wenn diese Tasten deaktiviert sind. Ich würde einen anderen Weg vorschlagen.

Eine jQuery-Plugin, es zu lösen

Wir lösen dieses Problem nur mit dem folgenden Code. Der Trick hier ist mit jQuery data() das Formular zu markieren, wie bereits vorgelegt oder nicht. Auf diese Weise haben wir nicht zu verwirren mit den Submit-Buttons, die Freaks IE aus.

// 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;
};

Verwenden Sie es wie folgt aus:

$('form').preventDoubleSubmission();

Wenn es AJAX Formen, die sollte erlaubt werden mehrmals pro Seite laden zu senden, können Sie ihnen eine Klasse geben, die angibt, schließen sie dann von Ihrem Wähler wie folgt aus:

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

Andere Tipps

Timing-Ansatz ist falsch - wie Sie wissen, wie lange die Aktion auf dem Client-Browser nehmen

Wie

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

Wenn Formular abgeschickt wird, wird es alle einreichen Tasten deaktivieren innen.

Denken Sie daran, in Firefox, wenn Sie deaktivieren einen Knopf dieser Zustand in Erinnerung bleiben wird, wenn Sie zurück in die Geschichte eingehen. Um zu verhindern, dass Sie Taste auf Seite Last ermöglichen, zum Beispiel.

ich glaube, Nathan Long Antwort ist der Weg zu gehen. Für mich, ich bin mit clientseitige Validierung, so dass ich eine Bedingung nur hinzugefügt, dass das Formular gültig sein.

Bearbeiten . Ist dies nicht hinzugefügt wird, wird der Benutzer nie in der Lage sein, das Formular zu senden, wenn die clientseitige Validierung einen Fehler auftritt

        // 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 funktioniert nicht in Firefox. Wiederkehrende falsch ist Nicht-Standard, sollten Sie event.preventDefault() nennen. Und während wir gerade dabei sind, immer verwenden Zahnspange mit einem Kontrollkonstrukt .

Um alle bisherigen Antworten zusammenzufassen, hier ist ein Plugin, das die Arbeit erledigt und funktioniert 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;
    });
};

Um Adresse Kern3l, die Timing-Methode funktioniert für mich, nur weil wir einen Doppelklick von der Absenden-Button zu stoppen versuchen. Wenn Sie eine sehr lange Reaktionszeit auf eine Vorlage haben, empfehle ich ersetzen den Submit-Button oder ein Formular mit einer Schleuder.

Völlig Nachreichungen der Form blockiert, da die meisten der obigen Beispiele zu tun, hat einen schlechten Nebeneffekt: wenn ein Netzwerkfehler ist, und sie wollen erneut zu senden, um zu versuchen, würden sie nicht in der Lage sein, dies zu tun und würden verlieren die Änderungen sie gemacht. Dies würde auf jeden Fall einen ärgerlichen Benutzer machen.

Bitte Besuche jquery-safeform Plugin.

Anwendungsbeispiel:

$('.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;
    }
});

...aber das Formular wird nicht übermittelt jede von der POST-Daten soll es zu gehören.

Richtig.Deaktiviert form Elementnamen/Werte werden nicht an den server gesendet.Sie sollen Ihnen als readonly Elemente.

Auch, Anker können nicht deaktiviert werden, wie die.Sie müssen entfernen Ihre HREFs (nicht empfohlen) oder verhindern Sie, dass Ihre Standard-Verhalten (der bessere Weg), z.B.:

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

Nathans Code aber für jQuery Validate-Plugin

Wenn Sie zufällig jQuery Validate-Plugin zu nutzen, müssen sie bereits einreichen Handler implementiert, und in diesem Fall gibt es keinen Grund mehr zu implementieren als eine. Der 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;
    }
  }
});

Sie können es leicht erweitern im } else {-Block zu deaktivieren Eingängen und / oder Absenden-Button.

Prost

beenden ich mit Ideen aus diesem Beitrag oben mit einer Lösung zu kommen, der AtZako Version ziemlich ähnlich ist.

 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;
  });   
};

Unter Verwendung wie folgt aus:

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

Ich fand, dass die Lösungen, die nicht eine Art von Timeout sind aber nur deaktiviert Unterwerfung oder deaktiviert Formelemente verursacht Probleme, weil, sobald die Aussperrung ausgelöst wird Sie nicht erneut einreichen können, bis Sie die Seite aktualisieren. Das verursacht einige Probleme für mich, wenn Ajax Sachen zu tun.

Dies ist vermutlich ein wenig, als es ist nicht so extravagant verschönert werden.

Bei der Verwendung von AJAX ein Formular zu schreiben, Satz async: false zusätzliche vorträgt, bevor die Form Clears verhindern sollte:

$("#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;
   }
});

Modifizierte Nathans Lösung ein wenig für Bootstrap 3. Dies wird eine Lade Text auf die Schaltfläche zum Senden eingestellt. Darüber hinaus wird es nach 30 Sekunden und lassen Sie das Formular erneut gesendet werden.

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);
};

Mit zwei Tasten einreichen.

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

Und jQuery:

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

Ich habe mit ähnlichen Problemen und meine Lösung (en) sind wie folgt.

Wenn Sie eine Client-seitige Validierung nicht haben, dann können Sie einfach die jquery ein () -Methode wie hier dokumentiert.

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

Dies deaktiviert die Prozedur nach seinem aufgerufen.

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

Wenn Sie die Client-seitige Validierung tun wie ich tat dann seine etwas komplizierter. Das obige Beispiel würde nicht zulassen, Sie einreichen wieder nach gescheiterten Validierung. Versuchen Sie, diese Annäherung statt

$("#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);
   }
});

hier ist, wie ich es tun:

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

Credits: https://github.com/phpawy/jquery-submit-once

Mit einfachen Zähler auf einreichen.

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

Und Aufruf monitor() Funktion auf das Formular aus.

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

Dieser Code wird Laden auf die Schaltfläche Etikett anzuzeigen und Set-Taste, um

Sperrzustand, dann nach der Bearbeitung wieder aktivieren und den ursprünglichen Schaltfläche Text wieder zurück **

$(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
}

);

Meine Lösung:

// 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;
};

In meinem Fall der onsubmit der Form hatten einigen Validierungscode, so dass ich Zuwachs Nathan Long Antwort einen onsubmit Kontrollpunkt einschließlich

$.fn.preventDoubleSubmission = function() {
      $(this).on('submit',function(e){
        var $form = $(this);
        //if the form has something in onsubmit
        var submitCode = $form.attr('onsubmit');
        if(submitCode != undefined && submitCode != ''){
            var submitFunction = new Function (submitCode);
            if(!submitFunction()){
                event.preventDefault();
                return false;
            }                   
        }

        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;
    };

Ändern Submit-Button:

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

Mit normaler Taste:

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

Dann Funktion Verwendung Klick:

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

Und denken Sie daran Taste wieder aktivieren, wenn ist necesary: ??

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

Ich kann den guten alten CSS Trick von Zeiger-Ereignissen glaubt: keine noch nicht erwähnt worden. Ich hatte das gleiche Problem, das von einem beschädigten Attribute hinzugefügt, aber diese Posten nicht zurück. Versuchen Sie, die unten und ersetzt #SubmitButton mit der ID der Submit-Button.

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

Warum nicht nur diese - dies wird das Formular aber auch deaktivieren die einreichenden Taste,

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

Auch wenn Sie jQuery Validate verwenden, können Sie diese beiden Zeilen unter if ($('#myForm').valid()) setzen.

können Sie stoppen den einreichen zweite dieses

$("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
    });
});

Ich löste ein sehr ähnliches Problem mit:

$("#my_form").submit(function(){
    $('input[type=submit]').click(function(event){
        event.preventDefault();
    });
});
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top