jQuery - empêche la valeur par défaut, puis continue la valeur par défaut

104

J'ai un formulaire qui, une fois soumis, je dois effectuer un traitement supplémentaire avant de pouvoir le soumettre. Je peux empêcher le comportement de soumission de formulaire par défaut, puis effectuer mon traitement supplémentaire (il s'agit essentiellement d'appeler l'API Google Maps et d'ajouter quelques champs masqués au formulaire) - puis j'ai besoin du formulaire pour le soumettre.

Existe-t-il un moyen "d'empêcher la valeur par défaut", puis un peu plus tard "continuer par défaut?"

StackOverflowNewbie
la source
@FelixKling Voulez-vous dire stackoverflow.com/questions/7610871/... ?
M. Mimpen

Réponses:

53

Lorsque vous liez l' .submit()événement au formulaire et que vous faites les choses que vous voulez faire avant de retourner (vrai), ces choses se produisent avant la soumission réelle.

Par exemple:

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

Exemple simple

Un autre exemple sur jquery.com: http://api.jquery.com/submit/#entry-examples

Ron van der Heijden
la source
2
êtes-vous en train de dire que le formulaire ne sera pas soumis avant que tout le code avant le "retourne vrai"; l'instruction est exécutée?
developarvin
2
Oui, c'est exactement ce que fait la fonction submit () .
Ron van der Heijden
8
Ce n'est pas un bon exemple car c'est synchrone. Et si je dois faire un appel asynchrone? Donc le cas est "cliquez sur soumettre -> faites des trucs asynchrones et ne soumettez pas le formulaire -> dans le rappel asynchrone, remplissez certains champs du formulaire -> soumettez le formulaire à partir du rappel"
The Godfather
1
Qu'en est-il d'exécuter du code jQuery asynchrone?! Cela fonctionnera aussi?
candlejack
cela fonctionne très bien pour moi. Je l'utilise pour contrôler les choses avant de soumettre et si les choses ne sont pas bonnes, j'utilise "return false". J'ai cherché cette solution pendant un jour. Merci beaucoup.
direct du
53

Utilisation jQuery.one()

Attachez un gestionnaire à un événement pour les éléments. Le gestionnaire est exécuté au plus une fois par élément et par type d'événement

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

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

L'utilisation de oneprevent également une boucle infinie car cet submitévénement personnalisé est détaché après la première soumission.

Aurel
la source
2
il soumettra après avoir cliqué à nouveau :(
curiosité
Vous allez probablement faire face à une boucle infinie
Mehrdad HosseinNejad
Boucle infinie, la fonction doit être .on not .one
sgvolpe
26

Je ferais juste:

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

Appelez d' preventDefaultabord et utilisez la submit()fonction plus tard, si vous avez juste besoin de soumettre le formulaire

bipen
la source
n'impliquez pas de logique dans votre gestionnaire d'événements click. déléguer la responsabilité à d'autres.
Royi Namir
27
Cela suppose que vous cliquerez sur un bouton. Que faire si l'utilisateur clique simplement sur le bouton «Entrée» depuis le formulaire? Cela soumettra également le formulaire. Donc, ce n'est probablement pas une bonne idée de s'appuyer sur le bouton d'envoi.
StackOverflowNewbie
je
donnais
2
Dans tous les cas, l'extrait que vous avez donné ne fonctionnera que si l'utilisateur clique sur un bouton. Ce n'est pas ainsi que fonctionnent les formulaires. D'autres suggestions?
StackOverflowNewbie
lier le clic, empêcher sa valeur par défaut et déclencher le clic du bouton d'
envoi
18

En utilisant cette méthode, vous ferez une boucle sans fin sur votre JS. pour mieux faire, vous pouvez utiliser les éléments suivants

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.

J'espère que ça aide! Merci!

Joepreludian
la source
la meilleure façon en fait, variation avec fonction asynchrone - gist.github.com/BjornMelgaard/8ba0ee9d07c20dd8c8b3550c9df3e9ef
srghma
@bjornmelgaard Je dois me rappeler que l'asynchrone n'est pas standard .
Valerio Bozz
6

C'est, à mon humble avis, la solution la plus générique et la plus robuste (si vos actions sont déclenchées par l'utilisateur, par exemple «l'utilisateur clique sur un bouton»):

  • la première fois qu'un gestionnaire est appelé check, l'OMS l'a déclenché:
    • si un utilisateur l'a fait tigger - faites votre travail, puis déclenchez-le à nouveau (si vous le souhaitez) - par programme
    • sinon - ne rien faire (= "continuer par défaut")

A titre d'exemple, notez cette solution élégante pour ajouter "Êtes-vous sûr?" popup à n'importe quel bouton simplement en décorant un bouton avec un attribut. Nous continuerons conditionnellement le comportement par défaut si l'utilisateur ne se désiste pas.

1. Ajoutons à chaque bouton que nous voulons une fenêtre contextuelle "êtes-vous sûr" un texte d'avertissement:

<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. Attachez des gestionnaires à TOUS ces boutons:

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

C'est tout.

igorludi
la source
1
Très bonne réponse! Je ne savais pas que vous pouviez passer un argument supplémentaire à .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();
});
Udayantha Udy Warnasuriya
la source
3

Avec jQueryet une petite variation de la réponse de @ Joepreludian ci-dessus:

Points importants à garder à l'esprit:

  • .one(...) plutôt sur .on(...) or .submit(...)
  • namedfonction au lieu de anonymous functionpuisque nous le référencerons dans le 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...
    }
});

Vous pouvez modifier la valeur de la allIsWellvariable dans l'extrait ci-dessous en trueou falsepour tester la fonctionnalité:

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

Bonne chance...

Akash
la source
2

De manière purement Javascript, vous pouvez soumettre le formulaire après avoir empêché le défaut.

C'est parce que HTMLFormElement.submit() n'appelle jamais le onSubmit(). Nous nous appuyons donc sur cette bizarrerie de spécification pour soumettre le formulaire comme s'il n'avait pas de gestionnaire onsubmit personnalisé ici.

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

Voir ce violon pour une requête synchrone.


Attendre la fin d'une requête asynchrone est tout aussi simple:

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

Vous pouvez consulter mon violon pour un exemple de requête asynchrone.


Et si vous n'avez pas de promesses:

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

Et voici cette demande .

Alairock
la source
1

Vous pouvez utiliser e.preventDefault() ce qui arrêtera l'opération en cours.

que tu peux faire$("#form").submit();

 $('#form').submit(function (e)
{
    return !!e.submit;
});
if(blabla...)
{...
}
else
{
    $('#form').submit(
    {
        submit: true
    });
}
Royi Namir
la source
c'est très déroutant pour moi .. est-ce que ça ne va pas juste autour et autour?
dapidmini
1

"Injection de validation sans boucle d'envoi":

Je veux juste vérifier reCaptcha et d'autres choses avant la validation HTML5, alors j'ai fait quelque chose comme ça (la fonction de validation renvoie vrai ou faux):

$(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
la source