J'essaie d'empêcher la soumission automatique d'un formulaire, puis utilisez JavaScript pour remplacer le formulaire par du texte indiquant à l'utilisateur que le serveur traite le formulaire, et dans le rappel dans mon itinéraire `` post '' sur le serveur, l'utilisateur est envoyé au page de résultats une fois le traitement terminé avec les informations du formulaire Mais avant que le span puisse apparaître dans le HTML, le formulaire a déjà été soumis et la page attend une réponse du serveur. Si j'insère une fonction de temporisation, je peux forcer l'élément span à apparaître avant que le formulaire ne soit soumis, mais il doit y avoir une meilleure façon de le faire. J'ai essayé d'utiliser async await .then(), mais cela n'a pas non plus fonctionné - peut-être que le chargement de la plage ne peut pas terminer le rendu avant que le formulaire ne soit envoyé? - Merci

HTML et JS :

var proc = async () => {
    var form = document.getElementById('form');
    form.style.display = 'none';
    var span = document.getElementById('testSpan');
    span.style.display = 'block';

    //using this timeout I can get the span element to appear
    //window.setTimeout(() => {
        //document.getElementById('form').submit()
    //}, 500);
}

var btn = document.getElementById('submitBTN');

btn.addEventListener('click', async () => {
    await proc().then(document.getElementById('form').submit());
})
<span style='display : none' id="testSpan">processing...</span>
<form method="POST" action="/submit-form" id="form" onsubmit="event.preventDefault();">
    <input required id="linkInput" type="text" name="name" />
    <input id='submitBTN' type="button" value="Submit"/>
</form>
2
Dillon Meyer 24 févr. 2021 à 03:38

2 réponses

Meilleure réponse

À moins que vous n'utilisiez le massage d'arrière-plan Web Workers, l'insertion d'une fonction de délai d'expiration pour "forcer l'élément span à apparaître avant que le formulaire ne soit soumis" est votre seule solution. Parce que "rien n'est rendu jusqu'à ce que vous reveniez de JavaScript", vous avez correctement commenté setTimeout (sauf qu'une attente de 0 milliseconde vaut mieux que 500).

Quant à votre fonction asynchrone, elle s'exécutera en concordance avec votre processus principal, appelant votre soumission et attendant la fin de cette soumission. Eh bien, cette soumission tuera tout avant, en attendant une nouvelle page.

0
denis hebert 24 févr. 2021 à 16:25

Utiliser async et await ne transforme pas les choses en promesses. Vous allez devoir retourner une promesse pour utiliser une promesse.

Dans votre cause, vous devrez toujours utiliser un délai d'attente. En fin de compte, ce n'est pas vraiment différent de ce que vous appelez simplement la soumission dans le délai d'attente.

var proc = async() => {
  document.body.classList.add("submitting");
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve();
    }, 500);
  });
}

var btn = document.getElementById('submitBTN');
btn.addEventListener('click', () => {
  proc().then(() => document.getElementById('form').submit());
})
#testSpan,
.submitting form {
  display: none;
}


.submitting #testSpan {
  display: block;
}
<span id="testSpan">processing...</span>
<form method="POST" action="/submit-form" id="form" onsubmit="event.preventDefault();">
  <input required id="linkInput" type="text" name="name" />
  <input id='submitBTN' type="button" value="Submit" />
</form>
0
epascarello 24 févr. 2021 à 16:39