jQuery - Standard verhindern und dann Standard fortsetzen

101

Ich habe ein Formular, bei dessen Übermittlung ich eine zusätzliche Verarbeitung durchführen muss, bevor das Formular gesendet werden soll. Ich kann das Standardverhalten beim Senden von Formularen verhindern und dann meine zusätzliche Verarbeitung durchführen (es ruft im Grunde die Google Maps-API auf und fügt dem Formular einige versteckte Felder hinzu) - und dann muss das Formular gesendet werden.

Gibt es eine Möglichkeit, "Standard zu verhindern" und irgendwann "Standard fortsetzen"?

StackOverflowNewbie
quelle
@FelixKling Meinten Sie stackoverflow.com/questions/7610871/… ?
M. Mimpen

Antworten:

53

Verwenden jQuery.one()

Hängen Sie einen Handler an ein Ereignis für die Elemente an. Der Handler wird höchstens einmal pro Element und Ereignistyp ausgeführt

$('form').one('submit', function(e) {
    e.preventDefault();
    // do your things ...

    // and when you done:
    $(this).submit();
});

Die Verwendung von oneverhindern auch Endlosschleife, da dieses benutzerdefinierte submitEreignis nach dem ersten Senden ausgelöst wird.

Aurel
quelle
2
es wird nach erneutem Klicken einreichen :(
Neugier
Wahrscheinlich werden Sie mit Endlosschleife
konfrontiert
Endlosschleife, die Funktion sollte .on not .one
sgvolpe
51

Wenn Sie das .submit()Ereignis an das Formular binden und die gewünschten Aktionen ausführen, bevor Sie zurückkehren (true), geschieht dies vor der eigentlichen Übermittlung.

Beispielsweise:

$('form').submit(function(){
    alert('I do something before the actual submission');
    return true;
});

Einfaches Beispiel

Ein weiteres Beispiel auf jquery.com: http://api.jquery.com/submit/#entry-examples

Ron van der Heijden
quelle
2
Wollen Sie damit sagen, dass das Formular erst gesendet wird, wenn der gesamte Code vor "return true" steht? Anweisung wird ausgeführt?
Developarvin
2
Ja, genau das macht die Funktion submit () .
Ron van der Heijden
8
Es ist kein gutes Beispiel, weil es synchron ist. Was ist, wenn ich einen asynchronen Anruf ausführen muss? Der Fall ist also "Klicken Sie
The Godfather
1
Was ist mit asynchronem jQuery-Code?! Wird auch funktionieren?
Candlejack
Das funktioniert gut für mich. Ich benutze es, um Dinge vor dem Absenden zu kontrollieren und wenn die Dinge nicht richtig sind, benutze ich "return false". Ich habe einen Tag lang nach dieser Lösung gesucht. Vielen Dank.
Livefreeor
26

Ich würde einfach tun:

 $('#submiteButtonID').click(function(e){
     e.preventDefault();
     //do your stuff.
     $('#formId').submit();
 });

Rufen Sie preventDefaultzuerst an und verwenden Sie die submit()Funktion später, wenn Sie nur das Formular senden müssen

Bipen
quelle
Verwenden Sie keine Logik in Ihrem Click-Event-Handler. delegieren Sie es an andere Verantwortung.
Royi Namir
27
Dies setzt voraus, dass Sie sicher auf eine Schaltfläche klicken. Was ist, wenn der Benutzer nur die Eingabetaste im Formular drückt? Das wird auch das Formular senden. Daher ist es wahrscheinlich keine gute Idee, sich darauf zu verlassen, dass auf die Schaltfläche "Senden" geklickt wird.
StackOverflowNewbie
Ich gab nur ein Beispiel für einen Klick ... da auf der Frage keine verwandten Codes erwähnt wurden ...
Bipen
2
In jedem Fall funktioniert das von Ihnen angegebene Snippet nur, wenn der Benutzer auf eine Schaltfläche klickt. So funktionieren Formulare nicht. Irgendwelche anderen Vorschläge?
StackOverflowNewbie
Binden Sie den Klick, verhindern Sie seine Standardeinstellung und lösen Sie den Klick auf die Schaltfläche "
Senden" aus
18

Auf diese Weise erstellen Sie eine Endlosschleife für Ihr JS. Um dies besser zu machen, können Sie Folgendes verwenden

var on_submit_function = function(evt){
    evt.preventDefault(); //The form wouln't be submitted Yet.
    (...yourcode...)

    $(this).off('submit', on_submit_function); //It will remove this handle and will submit the form again if it's all ok.
    $(this).submit();
}

$('form').on('submit', on_submit_function); //Registering on submit.

Ich hoffe, es hilft! Vielen Dank!

Joepreludian
quelle
Der beste Weg, Variation mit asynchroner Funktion - gist.github.com/BjornMelgaard/8ba0ee9d07c20dd8c8b3550c9df3e9ef
srghma
@bjornmelgaard Ich muss bedenken, dass der Async nicht Standard ist .
Valerio Bozz
6

Dies ist meiner Meinung nach die allgemeinste und robusteste Lösung (wenn Ihre Aktionen vom Benutzer ausgelöst werden, z. B. "Benutzer klickt auf eine Schaltfläche"):

  • Wenn ein Handler zum ersten Mal als check bezeichnet wird, hat die WHO ihn ausgelöst:
    • Wenn ein Benutzer es ausgelöst hat - machen Sie Ihre Sachen und lösen Sie es dann erneut aus (wenn Sie möchten) - programmgesteuert
    • sonst - nichts tun (= "Standard fortsetzen")

Beachten Sie als Beispiel diese elegante Lösung zum Hinzufügen von "Sind Sie sicher?" Popup zu einer beliebigen Schaltfläche, indem Sie eine Schaltfläche mit einem Attribut dekorieren. Wir setzen das Standardverhalten unter bestimmten Bedingungen fort, wenn der Benutzer sich nicht abmeldet.

1. Fügen wir zu jeder Schaltfläche, die wir möchten, ein Warnhinweis "Sind Sie sicher" hinzu:

<button class="btn btn-success-outline float-right" type="submit"  ays_text="You will lose any unsaved changes... Do you want to continue?"                >Do something dangerous</button>

2. Befestigen Sie Handler an ALLEN solchen Schaltflächen:

$('button[ays_text]').click(function (e, from) {
    if (from == null) {  // user clicked it!
        var btn = $(this);
        e.preventDefault();
        if (confirm() == true) {
            btn.trigger('click', ['your-app-name-here-or-anything-that-is-not-null']);
        }
    }
    // otherwise - do nothing, ie continue default
});

Das ist es.

igorludi
quelle
1
Gute Antwort! Ich wusste nicht, dass Sie ein zusätzliches Argument an .trigger () übergeben können
James Hibbard
5
$('#myform').on('submit',function(event){
  // block form submit event
  event.preventDefault();

  // Do some stuff here
  ...

  // Continue the form submit
  event.currentTarget.submit();
});
Udayantha Udy Warnasuriya
quelle
3

Mit jQueryund einer kleinen Variation von @ Joepreludians Antwort oben:

Wichtige Punkte, die Sie beachten sollten:

  • .one(...) anstatt .on(...) or .submit(...)
  • namedFunktion statt anonymous functionda wir es innerhalb der verweisen werden callback.

$('form#my-form').one('submit', function myFormSubmitCallback(evt) {
    evt.stopPropagation();
    evt.preventDefault();
    var $this = $(this);
    if (allIsWell) {
        $this.submit(); // submit the form and it will not re-enter the callback because we have worked with .one(...)
    } else {
        $this.one('submit', myFormSubmitCallback); // lets get into the callback 'one' more time...
    }
});

Sie können den Wert der allIsWellVariablen im folgenden Snippet ändern trueoder falsedie Funktionalität testen:

$('form#my-form').one('submit', function myFormSubmitCallback(evt){
  evt.stopPropagation();
  evt.preventDefault();
  var $this = $(this);
  var allIsWell = $('#allIsWell').get(0).checked;
  if(allIsWell) {
    $this.submit();
  } else {
    $this.one('submit', myFormSubmitCallback);
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form action="/" id="my-form">
  <input name="./fname" value="John" />
  <input name="./lname" value="Smith" />
  <input type="submit" value="Lets Do This!" />
  <br>
  <label>
    <input type="checkbox" value="true" id="allIsWell" />
    All Is Well
  </label>
</form>

Viel Glück...

Akash
quelle
2

Auf reine Javascript-Weise können Sie das Formular senden, nachdem Sie die Standardeinstellung verhindert haben.

Dies liegt daran , HTMLFormElement.submit() nie ruft die onSubmit(). Wir verlassen uns also auf diese Seltsamkeit der Spezifikation, um das Formular so einzureichen, als ob es hier keinen benutzerdefinierten Onsubmit-Handler hätte.

var submitHandler = (event) => {
  event.preventDefault()
  console.log('You should only see this once')
  document.getElementById('formId').submit()
}

Siehe diese Geige für eine synchrone Anfrage.


Das Warten auf den Abschluss einer asynchronen Anforderung ist genauso einfach:

var submitHandler = (event) => {
  event.preventDefault()
  console.log('before')
  setTimeout(function() {
    console.log('done')
    document.getElementById('formId').submit()
  }, 1400);
  console.log('after')
}

Sie können meine Geige nach einem Beispiel für eine asynchrone Anforderung durchsuchen.


Und wenn Sie mit Versprechungen unten sind:

var submitHandler = (event) => {
  event.preventDefault()
  console.log('Before')
    new Promise((res, rej) => {
      setTimeout(function() {
        console.log('done')
        res()
      }, 1400);
    }).then(() => {
      document.getElementById('bob').submit()
    })
  console.log('After')
}

Und hier ist diese Bitte .

Alairock
quelle
1

Sie können verwenden e.preventDefault() , um den aktuellen Vorgang zu stoppen.

als du tun kannst$("#form").submit();

 $('#form').submit(function (e)
{
    return !!e.submit;
});
if(blabla...)
{...
}
else
{
    $('#form').submit(
    {
        submit: true
    });
}
Royi Namir
quelle
Das ist sehr verwirrend für mich. Wird das nicht einfach so herumgehen?
Dapidmini
1

"Validierungsinjektion ohne Submit-Schleife":

Ich möchte nur reCaptcha und einige andere Dinge vor der HTML5-Validierung überprüfen, also habe ich so etwas gemacht (die Validierungsfunktion gibt true oder false zurück):

$(document).ready(function(){
   var application_form = $('form#application-form');

   application_form.on('submit',function(e){

        if(application_form_extra_validation()===true){
           return true;
        }

        e.preventDefault();

   });
});
Dennis Heiden
quelle