Reputation: 604
I have a dynamic form that at the moment of submit needs to be synchronous, I already know that jquery does this with ajax, but in my case I can't use jquery, is it possible to do this with plain JS?
my code:
//I need put the loading GIF from here.
//create dynamic form
var formularioElement = document.createElement('form');
formularioElement.setAttribute('id', 'formSync');
formularioElement.method = 'POST';
formularioElement.action = 'ExportReport';
// Create input
var formularioInput = document.createElement('input');
formularioInput.type = 'text';
formularioInput.name = 'typeFile';
formularioInput.value = varTypeFile;
formularioElement.appendChild(formularioInput);
// add the form to DOM
document.body.appendChild(formularioElement);
// submit
formularioElement.submit();
//Take off loading GIF from here
i need this because want put a load gif while the report is load, and with my current code, the GIF appears and disappears in less than a second, even if processing in the backend takes more than 1 minute If somebody have another solution i apreciate!
Upvotes: 0
Views: 764
Reputation: 2452
jQuery does not make it synchronous, nor can it. If you're wondering how to do this with plain JS then use XHR or fetch (I expect, but do not know, that jQuery uses XHR under the hood).
Fetch example (from https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch)
var form = new FormData(document.getElementById('login-form'));
fetch("/login", {
method: "POST",
body: form
});
This is only half your puzzle though.
Fetch
will return a promise, which could be used to do something else when the promise resolves/rejects. The promise will resolve when your fetch request completes, it will reject if the request fails. It works like this so that the JS thread is not blocked and can perform other operations whilst waiting for I/O.
For example, you might do something like:
loadingImageEl.style.display = 'block'
fetch('/route', {
method: 'POST',
body: form
})
.then(() => {
loadingImageEl.style.display = 'none'
})
This just shows and hides the loading image, you might want to create and destroy it.
There are many many libraries out there that could also be used instead of 'native' fetch, such as axios, which has a very similar api using promises.
If you really like the structure of synchronous calls then you could investigate using generators and yield, although using async-await
is a more natural fit. It would end up looking something like:
async function loadReport (reportName) {
const spinner = createLoadingSpinner()
await fetchReport (reportName)
destroyLoadingSpinner(spinner)
}
Note that support for async-await is currently sketchy, but solutions involving transpilation (such as babel) make this a viable option.
Upvotes: 2