I have an Ajax call that updates 5,000 records in a database so this takes a lot of time. I have an Ajax "Loading image" showing that something is happening, but I am looking for a better way to show "Updating 50 of 5000 . . .", "Updating 200 of 5000", or something like that.
What is the best way to do something like this in Ajax / jQuery without doing 5000 different posts?
The best I think is using Comet.
In Comet-style applications, the server can essentially push data to the client (instead of the client request data from the server again and again.). The client needs to only connect to server once. and then server will keep pushing data back to client.
From Wikipedia:
Comet is a programming technique that enables web servers to send data to the client without having any need for the client to request it. It allows creation of event-driven web applications which are hosted in the browser.
And now let's see how Comet works. See the following server-side code. here a while
loop is being used, you can instead set your own condition. In the while loop, the page writes a datetime and flushes and then sleeps for 1/2 seconds.
ASP.NET page code-behind: Service.aspx.cs
public static string Delimiter = "|";
protected void Page_Load(object sender, EventArgs e)
{
Response.Buffer = false;
while (true)
{
Response.Write(Delimiter
+ DateTime.Now.ToString("HH:mm:ss.FFF"));
Response.Flush();
// Suspend the thread for 1/2 a second
System.Threading.Thread.Sleep(500);
}
// Yes I know we'll never get here,
// it's just hard not to include it!
Response.End();
}
Client side code - pure JavaScript
Only make the request once, and then keep checking the data in the readyState === 3
of XMLHttpRequest
.
function getData()
{
loadXMLDoc("Service.aspx");
}
var req = false;
function createRequest() {
req = new XMLHttpRequest(); // http://msdn.microsoft.com/en-us/library/ms535874%28v=vs.85%29.aspx
}
function loadXMLDoc(url) {
try {
if (req) { req.abort(); req = false; }
createRequest();
if (req) {
req.onreadystatechange = processReqChange;
req.open("GET", url, true);
req.send("");
}
else { alert('unable to create request'); }
}
catch (e) { alert(e.message); }
}
function processReqChange() {
if (req.readyState == 3) {
try {
ProcessInput(req.responseText);
// At some (artibrary) length recycle the connection
if (req.responseText.length > 3000) { lastDelimiterPosition = -1; getData(); }
}
catch (e) { alert(e.message); }
}
}
var lastDelimiterPosition = -1;
function ProcessInput(input) {
// Make a copy of the input
var text = input;
// Search for the last instance of the delimiter
var nextDelimiter = text.indexOf('|', lastDelimiterPosition + 1);
if (nextDelimiter != -1) {
// Pull out the latest message
var timeStamp = text.substring(nextDelimiter + 1);
if (timeStamp.length > 0) {
lastDelimiterPosition = nextDelimiter;
document.getElementById('outputZone').innerHTML = timeStamp;
}
}
}
window.onload = function () { getData(); };