Reputation: 39
I would like to toggle a spinner on a form submission that returns a FileResult
from the server after some processing. However, since I do not refresh the page, the spinner does not get disabled automatically with my current implementation.
I would like to avoid roundabout methods that involve refreshing the page or downloading the file using JavaScript, if possible.
Below is a modified version of my page as a code snippet. In my actual code, I use @using (Html.BeginForm())
instead of a raw HTML form.
window.onload = function() {
$("form").on("submit", function() {
startSpinner();
});
};
window.onbeforeunload = function() {
stopSpinner();
};
function startSpinner() {
$(".overlay").css("display", "initial");
}
function stopSpinner() {
$(".overlay").css("display", "none");
}
.overlay {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: rgba(0, 0, 0, 0.3);
z-index: 9999;
}
.loader {
position: fixed;
left: 50%;
top: 50%;
margin-left: -50px;
margin-top: -50px;
width: 100px;
}
.loader:before {
content: '';
display: block;
padding-top: 100%;
}
.circular {
-webkit-animation: rotate 2s linear infinite;
animation: rotate 2s linear infinite;
height: 100%;
-webkit-transform-origin: center center;
transform-origin: center center;
width: 100%;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
}
.path {
stroke-dasharray: 1, 200;
stroke-dashoffset: 0;
-webkit-animation: dash 1.5s ease-in-out infinite, color 6s ease-in-out infinite;
animation: dash 1.5s ease-in-out infinite, color 6s ease-in-out infinite;
stroke-linecap: round;
}
@-webkit-keyframes rotate {
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@keyframes rotate {
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@-webkit-keyframes dash {
0% {
stroke-dasharray: 1, 200;
stroke-dashoffset: 0;
}
50% {
stroke-dasharray: 89, 200;
stroke-dashoffset: -35px;
}
100% {
stroke-dasharray: 89, 200;
stroke-dashoffset: -124px;
}
}
@keyframes dash {
0% {
stroke-dasharray: 1, 200;
stroke-dashoffset: 0;
}
50% {
stroke-dasharray: 89, 200;
stroke-dashoffset: -35px;
}
100% {
stroke-dasharray: 89, 200;
stroke-dashoffset: -124px;
}
}
@-webkit-keyframes color {
100%, 0% {
stroke: #d62d20;
}
40% {
stroke: #0057e7;
}
66% {
stroke: #008744;
}
80%,
90% {
stroke: #ffa700;
}
}
@keyframes color {
100%, 0% {
stroke: #d62d20;
}
40% {
stroke: #0057e7;
}
66% {
stroke: #008744;
}
80%,
90% {
stroke: #ffa700;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="overlay" style="display: none;">
<div class="loader">
<svg class="circular" viewBox="25 25 50 50">
<circle class="path" cx="50" cy="50" r="20" fill="none" stroke-width="5" stroke-miterlimit="10" />
</svg>
</div>
</div>
<!-- Some fields... -->
<form>
<button type="submit" class="btn btn-primary" id="analysis-submit-btn">Submit</button>
</form>
Typical controller method:
var myPackage = myFunction(myParameters);
var myFileName = "filename";
return File(myPackage, MediaTypeNames.Application.Octet, myFileName);
Upvotes: 0
Views: 1154
Reputation: 9881
Since you are doing a full POST, instead of an ajax call and are returning a file, instead of refreshing the view, you are somewhat limited to what you can do.
Looks like someone came up with a fairly innovative solution to this very problem:
It involves setting a cookie from the controller that returns the file. Then when you submit the form, you start checking to see if you have that cookie. If you have that cookie, it means the request has been sent down to the user.
Upvotes: 2