2010-12-27 5 views
12

Ich muss das Doppelklick-Sendeverhalten vermeiden. Ich verwende die Client-Validierung mit der unauffälligen Bibliothek. Ich habe den folgenden Code, um die Doppel clic zur Vermeidung von:ASP.NET MVC - Wie zu verhindern, Doppelklick senden mit jquery.validate.unobtrusive lib?

jQuery.fn.preventDoubleSubmit = function() { 
     var alreadySubmitted = false; 
     return jQuery(this).submit(function() { 

      if (alreadySubmitted) 
       return false; 
      else { 
       alreadySubmitted = true; 
      } 
     }); 
    }; 

    jQuery('form').preventDoubleSubmit(); 

Leider, wenn meine Form einige validierbaren Felder hat (zum Beispiel ein erforderliches Feld), über den Code immer noch gebrannt wird, also, selbst wenn ich richtig irgendwelche Fehler auf dem Formular, ich kann es nicht erneut einreichen.

Wie kann ich den Doppelklick-Code auslösen, nachdem die Validierung erfolgreich durchgeführt wurde?

Antwort

7

Ich löste es mit dem folgenden Code:

var tryNumber = 0; 
jQuery('input[type=submit]').click(function (event) { 
    var self = $(this); 

    if (self.closest('form').valid()) { 
     if (tryNumber > 0) { 
      tryNumber++; 
      alert('Your form has been already submited. wait please'); 
      return false; 
     } 
     else { 
      tryNumber++; 
     } 
    }; 
}); 

Hinweis: Sie können auch ersetzen die:

return false; 

Linie, für:

self.attr('disabled', true); 

ABER, wenn Sie verwenden Der Name Ihrer Submit-Buttons auf Ihrem Controller für zusätzliche Logik, sie werden als Null gesendet. (Können Sie ein zusätzliches verstecktes Feld verwenden, um sie aufzuladen, vor der Unterbreitung)

, die es ist, hoffe, es

Rodrigo

EDIT hilft: Dank dieser Beiträge: jquery newbie: combine validate with hidding submit button

16

Sie auch verwenden können die JQuery One event.

Ich habe festgestellt, dass ich durch Doppelklick schnell die meisten Wächter gegen Doppelklicks überwinden konnte. Die Verwendung des einzigen Ereignisses ist die einzige Möglichkeit, sicherzustellen, dass das Ereignis nur einmal ausgelöst wird. Ich denke nicht, dass diese Technik "out of the box" mit einem Eingabe-Typ = submit-Tag funktionieren wird. Stattdessen können Sie einfach einen Eingabetyp = Schaltfläche oder JQueryUI's .button() verwenden.

$("#submitButton").one("click", function(event) { 
    $('#theForm').submit(); 
}); 

Wenn Sie das Ereignis auf einem Fehler bei der Überprüfung (oder einem anderen Umstand) neu zu verkabeln müssen, empfehle ich, dass Sie eine Funktion für die Ereignishandler erstellen. Die Funktion ist in diesem Beispiel nicht erforderlich, da der gesamte Event-Handler das Formular absendet, aber in komplizierteren Szenarien möchten Sie möglicherweise vermeiden, dass Sie sich wiederholen.

function submitClick(event) { 
    $('#theForm').submit(); 
} 

$("#submitButton").one('click', function(event) { 
    submitClick(event); 
}); 

// This handler will re-wire the event when the form is invalid. 
$('#theForm').submit(function(event) { 
    if (!$(this).valid()) { 
     event.preventDefault(); 
     $('#submitButton').one('click', function(event) { submitClick(event); }); 
    } 
}); 

Sie könnten natürlich die Deaktivierung Code hier hinzufügen, wenn Sie Rückmeldung an den Benutzer, dass die Taste nicht mehr funktioniert geben wollen. Ein großer Nebeneffekt der Verwendung des One-Ereignisses ist, dass Sie die Schaltfläche nicht deaktivieren müssen, Sie können einen eigenen Stil verwenden.

function submitClick(event) { 
    $('#submitButton').addClass('disabledButton'); 
    $('#theForm').submit(); 
} 

$("#submitButton").one('click', function(event) { 
    submitClick(event); 
}); 

// This handler will re-wire the event when the form is invalid. 
$('#theForm').submit(function(event) { 
    if (!$(this).valid()) { 
     event.preventDefault(); 
     $('#submitButton').one('click', function(event) { submitClick(event); }); 
     $('#submitButton').removeClass('disabledButton'); 
    } 
}); 

JQuery Ein Ereignis:http://api.jquery.com/one/

+0

Großartig! Danke für die Info, das Verhalten wäre komplett mit diesem –

+0

Ich versuche den Javascript-Code, aber ich bekomme einen Fehler in $ (this) .valid() -Funktion. Es besagt, dass es keine gültige() Funktion für das Objekt $ (this) gibt. – miguelbgouveia

2

Warum nicht einfach:

function disableButtons() { 
    var form = $(this); 
    var btns = $("input:submit", form); 

    if (!form.valid()) { 
     // allow user to correct validation errors and re-submit 
     btns.removeAttr("disabled"); 
    } else { 
     btns.attr("disabled", "disabled"); 
    } 
} 

Ihre Tasten deaktivieren und aktivieren Sie es mit:

$("form").bind("submit", disableButtons); 
1

ich ein Formular das verwendet MVC3 unauffällige Validierung, a nd ein Viewmodel mit einem [RemoteAttribute]. Es sieht für mich so aus, als ob das Sendeereignis des Formulars nur ausgelöst wird, nachdem alle Prüfungen bestanden wurden. Ich verwende diese zur Zeit, und es scheint zu funktionieren:

<input type="submit" value="Submit the Form" 
    data-app-disable-on-submit="true" /> 

$('form').live('submit', function() { 
    $(this).find('input[type="submit"][data-app-disable-on-submit="true"]') 
       .attr('disabled', 'disabled'); 
}) 

;

Ich habe Breakpoints sowohl für die Remote-Attributüberprüfungs-Aktionsmethode als auch die HttpPost-Aktionsmethode festgelegt. Wenn Sie zum ersten Mal auf den Übergabeknopf klicken, wird der Haltepunkt der Validierungsaktionsmethode erreicht. Zu diesem Zeitpunkt ist die Schaltfläche weiterhin aktiviert. Ich kann es mehrmals anklicken, und nach der Wiederaufnahme der Validierungsmethode wird die HttpPost nur einmal getroffen. Wenn die HttpPost-Taste gedrückt wird, ist die Schaltfläche zum Senden deaktiviert.

aktualisieren

Rechts sind Sie Alex. So eine aktualisierte Version der oben würde wie folgt aussehen:

$('form').on('submit', function() { 
    $(this).find('input[type="submit"][data-app-disable-on-submit="true"]') 
       .attr('disabled', 'disabled'); 
}) 
+0

'.live' ist veraltet, in diesem speziellen Fall durch' .on' oder '.submit' ersetzt. Auf jeden Fall hat es bei mir nicht funktioniert. – Alex

+0

Sauber und einfach. +1 –

3

Basierend auf Ryan P's popular answer ich die folgende generische Lösung geschaffen, die auch mit meiner Ajax-Form arbeitet.

dekorieren Sie Ihren kundenspezifischen Knopf mit der folgenden Klasse einreichen:

<button type="button" class="one-click-submit-button">Submit</button> 

Fügen Sie den folgenden auf Ihre JavaScript-Datei:

function OneClickSubmitButton() { 
    $('.one-click-submit-button').each(function() { 
     var $theButton = $(this); 
     var $theForm = $theButton.closest('form'); 

     //hide the button and submit the form 
     function tieButtonToForm() { 
      $theButton.one('click', function() { 
       $theButton.hide(); 
       $theForm.submit(); 
      }); 
     } 

     tieButtonToForm(); 

     // This handler will re-wire the event when the form is invalid. 
     $theForm.submit(function (event) { 
      if (!$(this).valid()) { 
       $theButton.show(); 
       event.preventDefault(); 
       tieButtonToForm(); 
      } 
     }); 
    }); 
} 

OneClickSubmitButton(); 

da dies eine Ajax-Form ist, dass wir die Handler neu geladen werden soll, wenn wir Servervalidierung fehlschlagen.

function MyForm_OnSuccess() { 
    if (true if your form passed validation logic) { 
     //do something since your form submitted successfully 
    } else { //validation failed on server 
     OneClickSubmitButton(); //reinitialize the button logic 
    } 
} 

Natürlich, wenn Sie Sie die ganze OneClickSubmitButton Funktion Geschäft weglassen können nicht Ajax-Formen haben und $('.one-click-submit-button').each(... direkt ausgeführt werden.

+0

Wird '$ theForm.submit()' wirklich benötigt? Das Formular wird trotzdem gesendet. Ich entfernte es in [meine Antwort] (http://stackoverflow.com/a/21889861/1152054) und es scheint gut zu funktionieren. –

0

Erweitert die Antworten von Alex und Ryan P auf Konten für Situationen, in denen jQuery Validation fehlt und mehrere Übergabeschaltflächen in einem einzigen Formular vorhanden sind.

oneClickSubmitButton = function() { 
    $('input[type=submit], button[type=submit], input[type=image]').each(function() { 
     var $theButton = $(this); 
     var $theForm = $theButton.closest('form'); 

     //hide the button and submit the form 
     function tieButtonToForm() { 
      $theButton.one('click', function() { 
       $theButton.addClass('ui-state-disabled'); 
      }); 
     } 

     tieButtonToForm(); 

     $theForm.submit(function (event) { 
      // Only proceed for the clicked button 
      if (!$theButton.hasClass("ui-state-disabled")) 
       return; 

      // If jQuery Validation is not present or the form is valid, the form is valid 
      if (!$theForm.valid || $theForm.valid()) 
       return; 

      // Re-wire the event 
      $theButton.removeClass('ui-state-disabled'); 
      event.preventDefault(); 
      tieButtonToForm(); 
     }); 
    }); 
}; 
0
$('form').submit(function() { 
$('input[type="submit"]', this).attr('disabled', 'disabled'); 
    }); 
1

Ich verwende einen anderen Ansatz dazu. Keine Verbindung zum Klickereignis der Schaltfläche, sondern zum Sendeereignis des Formulars. Funktioniert wie ein Zauber, um mehrere gleichzeitige Übergaben von Formularen zu verhindern.

function initFormsToPreventSimultaneousSubmits(selector) { 
    if (!selector) { 
     selector = 'form'; // No selector supplied, apply to all forms on the page 
    } 

    // Make sure all forms that conform to selector are marked as not submitting 
    $(selector).each(function() 
    { 
     var $form = $(this); 
     $form.data('submitting', false); 
    }); 

    // Attach to submit event of all forms that conform to selector 
    $(selector).off('submit').on('submit', function (e) { 
     var $form = $(this); 

     if (!$form.valid || $form.valid()) { // Make sure to only process when the form is valid or jquery validation is not used 
      if ($form.data('submitting')) { 
       // form is already submitting. Classic case of double click on one of the submit buttons of the form. Stop the submit 
       e.preventDefault(); 
       return false; 
      } else { 
       // All ok, mark the form as submitting and let the form perform the submit 
       $form.data('submitting', true); 
       return true; 
      } 
     } 
    }); 
} 

Auf Dokument bereit i nennen initFormsToPreventSimultaneousSubmits() alle Formen auf der Seite init.

Nur daran zu erinnern ist, dass, wenn Sie eine Ajax-Form post verwenden, die initFormsToPreventSimultaneousSubmits ('# formId') auf dem OnComplete-Ereignis der AjaxOptions-Einstellungen aufrufen. Denn ansonsten wird das Formular immer noch als Senden markiert, wenn es fertig ist. Wenn ein "normaler" Formularpost verwendet wird, ist dies kein Problem.

0

Ich konnte ein ähnliches Problem mit ein paar Zeilen Code beheben. Ich ziehe das vor, wenn Sie dem Benutzer nicht "melden" möchten, dass er doppelt geklickt hat, und den zweiten Klick ignorieren.

Ich habe gerade eine globale Javascript-Variable gemacht, die ich wechselte, wenn meine Funktion während eines kritischen Abschnitts ausgeführt wurde. Dadurch wurde verhindert, dass nachfolgende Funktionsaufrufe denselben Abschnitt erneut ausführen.

var criticalSection = false; 

SomeOnClickEventFired = function() { 
     if (!criticalSection) 
     { 
      criticalSection = true; 
      //Ajax Time 
      criticalSection = false; 
     } 
}