Reputation: 734
Simply, I want to show a spinning div on the page load until the page complete an async task that bring data from a database. While you can see a lot of samples on how to show a spinning loader during page load, no one specify the case of async page load where all examples are failing.
To simulate the case, I did the following:
Create a new Web application (Web Forms), and in the default page, just await Task.Delay(6000);
to simulate my database call and then ScriptManager.RegisterStartupScript(Page, this.GetType(), "HideLoader", "HideLoader();", true);
to hide the spinning div. (or supposedly, use JavaScript event like document ready, window load, document load...). In page async load, all JavaScript event will fire after the async task!!!
I Put <div id="loader" class="loader center"></div>
in the site master.
add a script to hide the spinning div when the page is fully loaded. I used all possible events to see which one is hitting first:
$(document).ready(function () {
console.log('document ready: ' + GenerateDate());
});
$(window).on('load', function () {
console.log('window load: ' + GenerateDate());
});
$(document).on('load', function () {
console.log('document load: ' + GenerateDate());
});
document.onreadystatechange = function () {
if (document.readyState !== "complete") {
document.querySelector(
"body").style.visibility = "hidden";
document.querySelector(
"#loader").style.visibility = "visible";
console.log('document.onreadystatechange: ' + document.readyState + ': setting body to hidden and loader to visible : ' + GenerateDate());
} else {
document.querySelector(
"body").style.visibility = "visible";
document.querySelector(
"#loader").style.display = "none";
console.log('document.onreadystatechange: ' + document.readyState + ': setting body visible : ' + GenerateDate());
}
};
function HideLoader() {
document.querySelector(
"#loader").style.display = "none";
document.querySelector(
"body").style.visibility = "visible";
console.log('HideLoader from code behind: setting loader to none and body to visible ' + GenerateDate());
}
function GenerateDate() {
var d = new Date();
var h = addZero(d.getHours(), 2);
var m = addZero(d.getMinutes(), 2);
var s = addZero(d.getSeconds(), 2);
var ms = addZero(d.getMilliseconds(), 3);
var fullDate = h + ":" + m + ":" + s + ":" + ms;
return fullDate;
}
function addZero(x, n) {
while (x.toString().length < n) {
x = "0" + x;
}
return x;
}
Finally, the spinning div is not showing at all. it shows an hide immediately.
Upvotes: 0
Views: 1230
Reputation: 49169
Ok, well, since this IS ON page load?
Then setup the page to show the spinner by default.
Then let page load, then after page is loaded, you call/run your longer running task.
Lets have a simple example.
<asp:Button ID="cmdLongRun"
runat="server" Text="run long code load grid"
ClientIDMode="Static" OnClick="cmdLongRun_Click"
style="display:none"/>
<br />
<div id="myspin" runat="server" style="display:normal">
<img src="Content/wait2.gif" /><br />
</div>
<asp:GridView ID="GridView1" runat="server"
CssClass="table" Width="40%" >
</asp:GridView>
When the page loads, we will load up a gridview. But, lets assume that the process takes say a few seconds.
So, page will load - the spinner as above will display.
(we could have 2 div - one around the grid view, but our gridview has no data - so it don't display and we don't care - but this I suppose could in theory be 2 divs).
So, we let the page load and THEN using script, click on our above button.
So, our code to load this up is this:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If IsPostBack = False Then
' first page load - so after page loads, run a start up script that clicks
' a button on the page to run the code behind long runnnig task.
Dim strJava As String = "$('#cmdLongRun').click();"
Page.ClientScript.RegisterStartupScript(Me.GetType(), "My Load script", strJava, True)
End If
End Sub
Protected Sub cmdLongRun_Click(sender As Object, e As EventArgs)
Using conn As New SqlConnection(My.Settings.TEST4)
Dim strSQL As String =
"SELECT FirstName, LastName, City, HotelName, Description
FROM tblHotelsA ORDER BY HotelName"
Using cmdSQL As New SqlCommand(strSQL, conn)
conn.Open()
Dim rstData As New DataTable
rstData.Load(cmdSQL.ExecuteReader)
GridView1.DataSource = rstData
GridView1.DataBind()
End Using
End Using
' fake a long delay
System.Threading.Thread.Sleep(3000) ' 3 seond delay
myspin.Style("Display") = "none" ' hide spinner
End Sub
Now I assumed jQuery (for the button click + selector). So, we let page load (by default display spinner).
Then page loads, and we injected that button click to click on our button.
Long run button code runs (while spinner is displayed). When long running code is done that same code hides spinner. Page cycle completes, and our gird displays.
You can use jQuery to trigger after page load. Like this:
$(document).ready(loadmytextbox())
function loadmytextbox() {
if (IsPostBack() != true) {
$('#NotesEdit').hide();
$('#noteswait').show();
$.ajax({
type: 'POST',
url: 'IssueEdit.aspx/GetNotes',
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: OnGotText,
failure: function (response) {
alert(response.d);
}
});
}
function OnGotText(response) {
var tbox = document.getElementById('txtNotes_HtmlEditorExtender_ExtenderContentEditable');
var buf = response.d;
tbox.innerHTML = buf;
buf = "";
// tbox.innerHTML = 'back from service';
$('#NotesEdit').show();
$('#noteswait').hide();
}
}
So, in above, noteswait is a spinner. On document.Ready() we call our js code to load up some data into a text box, but I show a spinner while this occurs (noteswait.Show).
Upvotes: 1