jQuery: previene il valore predefinito, quindi continua il valore predefinito


104

Ho un modulo che, una volta inviato, devo eseguire alcune elaborazioni aggiuntive prima di inviare il modulo. Posso impedire il comportamento di invio del modulo predefinito, quindi eseguire la mia elaborazione aggiuntiva (fondamentalmente chiama l'API di Google Maps e aggiunge alcuni campi nascosti al modulo) - e quindi ho bisogno del modulo da inviare.

C'è un modo per "prevenire il default", quindi un punto dopo "continuare il default?"


Risposte:


53

Quando leghi l' .submit()evento al modulo e fai le cose che vuoi fare prima di tornare (vero), queste cose accadono prima dell'effettivo invio.

Per esempio:

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

Semplice esempio

Un altro esempio su jquery.com: http://api.jquery.com/submit/#entry-examples


2
stai dicendo che il modulo non verrà inviato fino a quando tutto il codice prima del "return true;" istruzione viene eseguita?
Developarvin

2
Sì, è esattamente ciò che fa la funzione submit () .
Ron van der Heijden

8
Non è un buon esempio perché è sincrono. E se ciò che devo fare è una chiamata asincrona? Quindi il caso è "fai clic su invia -> fai cose asincrone e non inviare il modulo -> in richiamata asincrona compila alcuni campi del modulo -> invia il modulo dalla richiamata"
The Godfather

1
Che ne dici di eseguire del codice jQuery asincrono ?! Funzionerà anche tu?
Candlejack

questo funziona alla grande per me. Lo uso per controllare le cose prima dell'invio e se le cose non vanno bene uso "return false". Ho cercato questa soluzione per un giorno. molte grazie.
livefree o

53

Uso jQuery.one()

Associa un gestore a un evento per gli elementi. Il gestore viene eseguito al massimo una volta per elemento per tipo di evento

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

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

L'uso di oneprevent anche loop infinito perché questo submitevento personalizzato viene detatched dopo il primo invio.


2
invierà dopo aver cliccato di nuovo :(
curiosità

Probabilmente affronterai un loop infinito
Mehrdad HosseinNejad

Ciclo infinito, la funzione dovrebbe essere .on non .one
sgvolpe il

26

Vorrei solo fare:

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

Chiama preventDefaultprima e usa la submit()funzione in seguito, se devi solo inviare il modulo


non coinvolgere la logica all'interno del gestore di eventi di clic. delegarlo ad altri responsabilità.
Royi Namir

27
Ciò presuppone che il sicuro faccia clic su un pulsante. Cosa succede se l'utente preme semplicemente il pulsante "Invio" dall'interno del modulo? Questo invierà anche il modulo. Quindi, probabilmente non è una buona idea fare affidamento sul pulsante di invio che viene cliccato.
StackOverflowNewbie

stavo solo facendo un esempio di clic ... poiché non c'erano codici correlati menzionati nella domanda ...
bipen

2
In ogni caso, lo snippet che hai fornito funzionerà solo se l'utente fa clic su un pulsante. Non è così che funzionano i moduli. Qualche altro suggerimento?
StackOverflowNewbie

vincola il clic, evita il suo valore predefinito e attiva il clic sul pulsante di invio
candlejack

18

Usando questo modo farai un loop infinito sul tuo JS. per fare un modo migliore puoi usare quanto segue

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.

Spero possa essere d'aiuto! Grazie!


il modo migliore in realtà, variazione con la funzione asincrona - gist.github.com/BjornMelgaard/8ba0ee9d07c20dd8c8b3550c9df3e9ef
srghma

@bjornmelgaard devo ricordare che l'asincronia non è standard .
Valerio Bozz

6

Questa è, secondo me, la soluzione più generica e robusta (se le tue azioni sono attivate dall'utente, ad esempio "l'utente fa clic su un pulsante"):

  • la prima volta che un gestore viene chiamato controlla CHI lo ha attivato:
    • se un utente lo ha attivato, fai le tue cose, quindi attivalo di nuovo (se lo desideri) - a livello di programmazione
    • altrimenti - non fare nulla (= "continua predefinito")

Ad esempio, nota questa elegante soluzione per aggiungere "Sei sicuro?" popup a qualsiasi pulsante semplicemente decorando un pulsante con un attributo. Continueremo in modo condizionale il comportamento predefinito se l'utente non rinuncia.

1. Aggiungiamo a ogni pulsante che vogliamo che venga visualizzato un messaggio di avviso:

<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. Collega i gestori a TUTTI questi pulsanti:

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

Questo è tutto.


1
Bella risposta! Non sapevo che potessi passare un argomento in più a .trigger ()
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();
});

3

Con jQuerye una piccola variazione della risposta di @ Joepreludian sopra:

Punti importanti da tenere a mente:

  • .one(...) invece su .on(...) or .submit(...)
  • named funzione invece di anonymous function poiché la faremo riferimento all'interno del file 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...
    }
});

Puoi modificare il valore della allIsWellvariabile nello snippet di seguito in trueo falseper testare la funzionalità:

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

In bocca al lupo...


2

In un puro modo Javascript, puoi inviare il modulo dopo aver impedito il default.

Questo perché HTMLFormElement.submit() non chiama mai il file onSubmit(). Quindi ci affidiamo a quella stranezza delle specifiche per inviare il modulo come se non avesse un gestore personalizzato onsubmit qui.

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

Vedi questo violino per una richiesta sincrona.


Attendere il completamento di una richiesta asincrona è altrettanto semplice:

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

Puoi controllare il mio violino per un esempio di una richiesta asincrona.


E se non hai le promesse:

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

Ed ecco quella richiesta .


1

È possibile utilizzare e.preventDefault()che interromperà l'operazione corrente.

di quello che puoi fare$("#form").submit();

 $('#form').submit(function (e)
{
    return !!e.submit;
});
if(blabla...)
{...
}
else
{
    $('#form').submit(
    {
        submit: true
    });
}

questo è molto confuso per me .. non sarà solo girare e girare?
dapidmini

1

"Iniezione di convalida senza ciclo di invio":

Voglio solo controllare reCaptcha e alcune altre cose prima della convalida HTML5, quindi ho fatto qualcosa del genere (la funzione di convalida restituisce vero o falso):

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

   });
});
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.