I am have an issue with a JS script I am trying to put together. I have an HTML table with somewhere in the neighborhood of 300 rows in it. I have made a sort function that will make the table headers clickable and launch my sort function. I would like to integrate a progress bar because in larger tables (500 - 1000 rows) after a header is clicked the table takes a bit of time to sort (IE is a big offender). The progress bar would tell them how much time remains before the sort is plete. The method I had in mind was a div element that I would resize based on the progression of the sort loop. The problem is that I can't seem to figure out how to integrate such a routine into my loop.
I've researched the issue and taken note of this: How to change progress bar in loop? and this: Using setTimeout to update progress bar when looping over multiple variables
The second topic has a few demos that do essentially what I would like to do as far as the progress bar goes. However, anytime I try to implement the solutions shown in those two posts I either:
A - Crash the browser
B - Progress bar appears to work, but goes from 0 - 100% instantly, not progressively.
I am hoping someone can lead me in the right direction on what to do. This table sort progress indicator must be done using native JS because the contents must be available offline, hence I can't include any jQuery libraries via CDN and bloating the document with the entire jQuery library isn't desired.
I've created a JS fiddle with my code in it. I've stripped out what I had for progress bar code because I kept crashing the browser so all that is there as far as scripts go is the sorting-related code. jsfiddle
Here is the JS itself:
//Change this variable to match the "id" attribute of the
//table that is going to be operated on.
var tableID = "sortable";
/**
* Attach click events to all the <th> elements in a table to
* call the tableSort() function. This function assumes that cells
* in the first row in a table are <th> headers tags and that cells
* in the remaining rows are <td> data tags.
*
* @param table The table element to work with.
* @return void
*/
function initHeaders(table) {
//Get the table element
table = document.getElementById(table);
//Get the number of cells in the header row
var l = table.rows[0].cells.length;
//Loop through the header cells and attach the events
for(var i = 0; i < l; i++) {
if(table.rows[0].cells[i].addEventListener) { //For modern browsers
table.rows[0].cells[i].addEventListener("click", tableSort, false);
} else if(table.rows[0].cells[i].attachEvent) { //IE specific method
table.rows[0].cells[i].attachEvent("onclick", tableSort);
}
}
}
/**
* Compares values in a column of a table and then sorts the table rows.
* Subsequent calls to this function will toggle a row between ascending
* and descending sort directions.
*
* @param e The click event passed in from the browser.
* @return mixed No return value if operation pletes successfully, FALSE on error.
*/
function tableSort(e) {
/**
* Checks to see if a value is numeric.
*
* @param n The ining value to check.
* @return bool TRUE if value is numeric, FALSE otherwise.
*/
tableSort.isNumeric = function (n) {
var num = false;
if(!isNaN(n) && isFinite(n)) {
num = true;
}
return num;
}
//Get the element from the click event that was passed.
if(e.currentTarget) { //For modern browsers
e = e.currentTarget;
} else if(window.event.srcElement) { //IE specific method
e = window.event.srcElement;
} else {
console.log("Unable to determine source event. Terminating....");
return false;
}
//Get the index of the cell, will be needed later
var ndx = e.cellIndex;
//Toggle between "asc" and "desc" depending on element's id attribute
if(e.id == "asc") {
e.id = "desc";
} else {
e.id = "asc";
}
//Move up from the <th> that was clicked and find the parent table element.
var parent = e.parentElement;
var s = parent.tagName;
while(s.toLowerCase() != "table") {
parent = parent.parentElement;
s = parent.tagName;
}
/*
Executes two different loops. A "for" loop to control how many
times the table rows are passed looking for values to sort and a
"while" loop that does the actual paring of values. The "for"
loop also controls how many times the embedded "while" loop will
run since each iteration with force at least one table row into
the correct position.
*/
//var interval = setInterval( function () { progress.updateProgress() } , 100);
var rows = parent.tBodies[0].rows.length; //Isolate and count rows only in the <tbody> element.
if(rows > 1) { //Make sure there are enough rows to bother with sorting
var v1; //Value 1 placeholder
var v2; //Value 2 placeholder
var tbody = parent.tBodies[0]; //Table body to manipulate
//Start the for loop (controls amount of table passes)
for(i = 0; i < rows; i++) {
var j = 0; //Counter for swapping routine
var offset = rows - i - 1; //Stops next loop from overchecking
// WANT TO UPDATE PROGRESS BAR HERE
//Start the while loop (controls number of parisons to make)
while(j < offset) {
//Check to make sure values can be extracted before proceeding
if(typeof tbody.rows[j].cells[ndx].innerHTML !== undefined && typeof tbody.rows[j + 1].cells[ndx].innerHTML !== undefined) {
//Get cell values and pare
v1 = tbody.rows[j].cells[ndx].innerHTML;
v2 = tbody.rows[j + 1].cells[ndx].innerHTML;
if(tableSort.isNumeric(v1) && tableSort.isNumeric(v2)) {
//Dealing with two numbers
v1 = new Number(v1);
v2 = new Number(v2);
if(v1 > v2) {
if(e.id == "asc") { //v1 moves down
tbody.insertBefore(tbody.rows[j + 1], tbody.rows[j]);
}
} else {
if(e.id == "desc") { //v1 moves down
tbody.insertBefore(tbody.rows[j + 1], tbody.rows[j]);
}
}
} else if(tableSort.isNumeric(v1) && !tableSort.isNumeric(v2)) {
//v2 is a string, v1 is a number and automatically wins
if(e.id == "asc") { //v1 moves down
tbody.insertBefore(tbody.rows[j + 1], tbody.rows[j]);
}
} else if(!tableSort.isNumeric(v1) && tableSort.isNumeric(v2)) {
//v1 is a string, v2 is a number and automatically wins
if(e.id == "desc") { //v1 moves down
tbody.insertBefore(tbody.rows[j + 1], tbody.rows[j]);
}
} else {
//Both v1 and v2 are strings, use localeCompare()
if(v1.localeCompare(v2) > 0) {
if(e.id == "asc") { //v1 moves down
tbody.insertBefore(tbody.rows[j + 1], tbody.rows[j]);
}
} else {
if(e.id == "desc") { //v1 moves down
tbody.insertBefore(tbody.rows[j + 1], tbody.rows[j]);
}
}
}
j++;
} else {
console.log("One of the values turned up undefined");
}
}
}
}
}
//Wait until DOM is ready and then initialize the table headers.
window.onload = function () {
initHeaders(tableID);
}
Thanks in advance to anyone who can point me in the right direction.
----- EDIT: ----- Okay so after reading the answers here and making some hefty modifications to how I was going about things I have e up with a much better solution. The progress bar isn't exactly what I wanted, but it is close. (Although I believe that it is showing up on the page just as the sorting is getting ready to finish up.)
I modified my loop to do a O(n log n) quick sort and instead of modifying the DOM directly I instead isolate the table rows to sort and copy them into an array. I then do the sort directly on the array and once it is finished I rebuild the rows and then remove the old rows and append the new ones in. The sort time has been reduced significantly.
Have a look: /
And here is the new JS code:
//Change this variable to match the "id" attribute of the
//table that is going to be operated on.
var tableID = "sortable";
/**
* Attach click events to all the <th> elements in a table to
* call the tableSort() function. This function assumes that cells
* in the first row in a table are <th> headers tags and that cells
* in the remaining rows are <td> data tags.
*
* @param table The table element to work with.
* @return void
*/
function initHeaders(table) {
//Get the table element
table = document.getElementById(table);
//Get the number of cells in the header row
var l = table.rows[0].cells.length;
//Loop through the header cells and attach the events
for(var i = 0; i < l; i++) {
if(table.rows[0].cells[i].addEventListener) { //For modern browsers
table.rows[0].cells[i].addEventListener("click", tableSort, false);
} else if(table.rows[0].cells[i].attachEvent) { //IE specific method
table.rows[0].cells[i].attachEvent("onclick", tableSort);
}
}
}
function tableSort(e) {
var runs = 0;
var pix = 0;
var ndx = 0;
var dir = "right";
var interval = false;
//Get the element from the click event that was passed.
if(e.currentTarget) { //For modern browsers
e = e.currentTarget;
} else if(window.event.srcElement) { //IE specific method
e = window.event.srcElement;
} else {
console.log("Unable to determine source event. Terminating....");
return false;
}
//Get the index of the cell, will be needed later
ndx = e.cellIndex;
//Toggle between "asc" and "desc" depending on element's id attribute
if(e.id == "asc") {
e.id = "desc";
} else {
e.id = "asc";
}
//Move up from the <th> that was clicked and find the parent table element.
var parent = e.parentElement;
var s = parent.tagName;
while(s.toLowerCase() != "table") {
parent = parent.parentElement;
s = parent.tagName;
}
//Get the rows to operate on as an array
var rows = document.getElementById("replace").rows;
var a = new Array();
for(i = 0; i < rows.length; i++) {
a.push(rows[i]);
}
//Show progress bar ticker
document.getElementById("progress").style.display = "block";
/**
* Show the progress bar ticker animation
*
* @param pix The current pixel count to set the <div> margin at.
*/
function updateTicker(pix) {
var tick = document.getElementById("progressTicker");
document.getElementById("progressText").style.display = "block";
document.getElementById("progressText").innerHTML = "Sorting table...please wait";
if(dir == "right") {
if(pix < 170) {
pix += 5;
tick.style.marginLeft = pix + "px";
} else {
dir = "left";
}
} else {
if(pix > 0) {
pix -= 5;
tick.style.marginLeft = pix + "px";
} else {
dir = "left";
}
}
interval = window.setTimeout( function () { updateTicker(pix); }, 25);
}
updateTicker(pix);
/**
* Checks to see if a value is numeric.
*
* @param n The ining value to check.
* @return bool TRUE if value is numeric, FALSE otherwise.
*/
isNumeric = function (n) {
var num = false;
if(!isNaN(n) && isFinite(n)) {
num = true;
}
return num;
}
/**
* Compares two values and determines which one is "bigger".
*
* @param x A reference value to check against.
* @param y The value to be determined bigger or smaller than the reference.
* @return TRUE if y is greater or equal to x, FALSE otherwise
*/
function pare(x, y) {
var bigger = false;
x = x.cells[ndx].textContent;
y = y.cells[ndx].textContent;
//console.log(e.id);
if(isNumeric(x) && isNumeric(y)) {
if(y >= x) {
bigger = (e.id == "asc") ? true : false;
} else {
bigger = (e.id == "desc") ? true : false;
}
} else {
if(y.localeCompare(x) >= 0) {
bigger = (e.id == "asc") ? true : false;
} else {
bigger = (e.id == "desc") ? true : false;
}
}
return bigger;
}
/**
* Performs a quicksort O(n log n) on an array.
*
* @param array The array that needs sorting
* @return array The sorted array.
*/
function nlognSort(array) {
runs++
if(array.length > 1) {
var big = new Array();
var small = new Array();
var pivot = array.pop();
var l = array.length;
for(i = 0; i < l; i++) {
if(pare(pivot,array[i])) {
big.push(array[i]);
} else {
small.push(array[i]);
}
}
return Array.prototype.concat(nlognSort(small), pivot, nlognSort(big));
} else {
return array;
}
}
//Run sort routine
b = nlognSort(a);
//Rebuild <tbody> and replace new with the old
var tbody = document.createElement("tbody");
var l = b.length;
for(i = 0; i < l; i++) {
tbody.appendChild(b.shift());
}
parent.removeChild(document.getElementById("replace"));
parent.appendChild(tbody);
tbody.setAttribute("id","replace");
setTimeout(function () {
document.getElementById("progress").style.display = "none";
document.getElementById("progressText").style.display = "none";
clearTimeout(interval);
},1500);
}
window.onload = function() {
initHeaders(tableID);
}
Thanks again everyone!!
I am have an issue with a JS script I am trying to put together. I have an HTML table with somewhere in the neighborhood of 300 rows in it. I have made a sort function that will make the table headers clickable and launch my sort function. I would like to integrate a progress bar because in larger tables (500 - 1000 rows) after a header is clicked the table takes a bit of time to sort (IE is a big offender). The progress bar would tell them how much time remains before the sort is plete. The method I had in mind was a div element that I would resize based on the progression of the sort loop. The problem is that I can't seem to figure out how to integrate such a routine into my loop.
I've researched the issue and taken note of this: How to change progress bar in loop? and this: Using setTimeout to update progress bar when looping over multiple variables
The second topic has a few demos that do essentially what I would like to do as far as the progress bar goes. However, anytime I try to implement the solutions shown in those two posts I either:
A - Crash the browser
B - Progress bar appears to work, but goes from 0 - 100% instantly, not progressively.
I am hoping someone can lead me in the right direction on what to do. This table sort progress indicator must be done using native JS because the contents must be available offline, hence I can't include any jQuery libraries via CDN and bloating the document with the entire jQuery library isn't desired.
I've created a JS fiddle with my code in it. I've stripped out what I had for progress bar code because I kept crashing the browser so all that is there as far as scripts go is the sorting-related code. jsfiddle
Here is the JS itself:
//Change this variable to match the "id" attribute of the
//table that is going to be operated on.
var tableID = "sortable";
/**
* Attach click events to all the <th> elements in a table to
* call the tableSort() function. This function assumes that cells
* in the first row in a table are <th> headers tags and that cells
* in the remaining rows are <td> data tags.
*
* @param table The table element to work with.
* @return void
*/
function initHeaders(table) {
//Get the table element
table = document.getElementById(table);
//Get the number of cells in the header row
var l = table.rows[0].cells.length;
//Loop through the header cells and attach the events
for(var i = 0; i < l; i++) {
if(table.rows[0].cells[i].addEventListener) { //For modern browsers
table.rows[0].cells[i].addEventListener("click", tableSort, false);
} else if(table.rows[0].cells[i].attachEvent) { //IE specific method
table.rows[0].cells[i].attachEvent("onclick", tableSort);
}
}
}
/**
* Compares values in a column of a table and then sorts the table rows.
* Subsequent calls to this function will toggle a row between ascending
* and descending sort directions.
*
* @param e The click event passed in from the browser.
* @return mixed No return value if operation pletes successfully, FALSE on error.
*/
function tableSort(e) {
/**
* Checks to see if a value is numeric.
*
* @param n The ining value to check.
* @return bool TRUE if value is numeric, FALSE otherwise.
*/
tableSort.isNumeric = function (n) {
var num = false;
if(!isNaN(n) && isFinite(n)) {
num = true;
}
return num;
}
//Get the element from the click event that was passed.
if(e.currentTarget) { //For modern browsers
e = e.currentTarget;
} else if(window.event.srcElement) { //IE specific method
e = window.event.srcElement;
} else {
console.log("Unable to determine source event. Terminating....");
return false;
}
//Get the index of the cell, will be needed later
var ndx = e.cellIndex;
//Toggle between "asc" and "desc" depending on element's id attribute
if(e.id == "asc") {
e.id = "desc";
} else {
e.id = "asc";
}
//Move up from the <th> that was clicked and find the parent table element.
var parent = e.parentElement;
var s = parent.tagName;
while(s.toLowerCase() != "table") {
parent = parent.parentElement;
s = parent.tagName;
}
/*
Executes two different loops. A "for" loop to control how many
times the table rows are passed looking for values to sort and a
"while" loop that does the actual paring of values. The "for"
loop also controls how many times the embedded "while" loop will
run since each iteration with force at least one table row into
the correct position.
*/
//var interval = setInterval( function () { progress.updateProgress() } , 100);
var rows = parent.tBodies[0].rows.length; //Isolate and count rows only in the <tbody> element.
if(rows > 1) { //Make sure there are enough rows to bother with sorting
var v1; //Value 1 placeholder
var v2; //Value 2 placeholder
var tbody = parent.tBodies[0]; //Table body to manipulate
//Start the for loop (controls amount of table passes)
for(i = 0; i < rows; i++) {
var j = 0; //Counter for swapping routine
var offset = rows - i - 1; //Stops next loop from overchecking
// WANT TO UPDATE PROGRESS BAR HERE
//Start the while loop (controls number of parisons to make)
while(j < offset) {
//Check to make sure values can be extracted before proceeding
if(typeof tbody.rows[j].cells[ndx].innerHTML !== undefined && typeof tbody.rows[j + 1].cells[ndx].innerHTML !== undefined) {
//Get cell values and pare
v1 = tbody.rows[j].cells[ndx].innerHTML;
v2 = tbody.rows[j + 1].cells[ndx].innerHTML;
if(tableSort.isNumeric(v1) && tableSort.isNumeric(v2)) {
//Dealing with two numbers
v1 = new Number(v1);
v2 = new Number(v2);
if(v1 > v2) {
if(e.id == "asc") { //v1 moves down
tbody.insertBefore(tbody.rows[j + 1], tbody.rows[j]);
}
} else {
if(e.id == "desc") { //v1 moves down
tbody.insertBefore(tbody.rows[j + 1], tbody.rows[j]);
}
}
} else if(tableSort.isNumeric(v1) && !tableSort.isNumeric(v2)) {
//v2 is a string, v1 is a number and automatically wins
if(e.id == "asc") { //v1 moves down
tbody.insertBefore(tbody.rows[j + 1], tbody.rows[j]);
}
} else if(!tableSort.isNumeric(v1) && tableSort.isNumeric(v2)) {
//v1 is a string, v2 is a number and automatically wins
if(e.id == "desc") { //v1 moves down
tbody.insertBefore(tbody.rows[j + 1], tbody.rows[j]);
}
} else {
//Both v1 and v2 are strings, use localeCompare()
if(v1.localeCompare(v2) > 0) {
if(e.id == "asc") { //v1 moves down
tbody.insertBefore(tbody.rows[j + 1], tbody.rows[j]);
}
} else {
if(e.id == "desc") { //v1 moves down
tbody.insertBefore(tbody.rows[j + 1], tbody.rows[j]);
}
}
}
j++;
} else {
console.log("One of the values turned up undefined");
}
}
}
}
}
//Wait until DOM is ready and then initialize the table headers.
window.onload = function () {
initHeaders(tableID);
}
Thanks in advance to anyone who can point me in the right direction.
----- EDIT: ----- Okay so after reading the answers here and making some hefty modifications to how I was going about things I have e up with a much better solution. The progress bar isn't exactly what I wanted, but it is close. (Although I believe that it is showing up on the page just as the sorting is getting ready to finish up.)
I modified my loop to do a O(n log n) quick sort and instead of modifying the DOM directly I instead isolate the table rows to sort and copy them into an array. I then do the sort directly on the array and once it is finished I rebuild the rows and then remove the old rows and append the new ones in. The sort time has been reduced significantly.
Have a look: http://jsfiddle/jnBmp/5/
And here is the new JS code:
//Change this variable to match the "id" attribute of the
//table that is going to be operated on.
var tableID = "sortable";
/**
* Attach click events to all the <th> elements in a table to
* call the tableSort() function. This function assumes that cells
* in the first row in a table are <th> headers tags and that cells
* in the remaining rows are <td> data tags.
*
* @param table The table element to work with.
* @return void
*/
function initHeaders(table) {
//Get the table element
table = document.getElementById(table);
//Get the number of cells in the header row
var l = table.rows[0].cells.length;
//Loop through the header cells and attach the events
for(var i = 0; i < l; i++) {
if(table.rows[0].cells[i].addEventListener) { //For modern browsers
table.rows[0].cells[i].addEventListener("click", tableSort, false);
} else if(table.rows[0].cells[i].attachEvent) { //IE specific method
table.rows[0].cells[i].attachEvent("onclick", tableSort);
}
}
}
function tableSort(e) {
var runs = 0;
var pix = 0;
var ndx = 0;
var dir = "right";
var interval = false;
//Get the element from the click event that was passed.
if(e.currentTarget) { //For modern browsers
e = e.currentTarget;
} else if(window.event.srcElement) { //IE specific method
e = window.event.srcElement;
} else {
console.log("Unable to determine source event. Terminating....");
return false;
}
//Get the index of the cell, will be needed later
ndx = e.cellIndex;
//Toggle between "asc" and "desc" depending on element's id attribute
if(e.id == "asc") {
e.id = "desc";
} else {
e.id = "asc";
}
//Move up from the <th> that was clicked and find the parent table element.
var parent = e.parentElement;
var s = parent.tagName;
while(s.toLowerCase() != "table") {
parent = parent.parentElement;
s = parent.tagName;
}
//Get the rows to operate on as an array
var rows = document.getElementById("replace").rows;
var a = new Array();
for(i = 0; i < rows.length; i++) {
a.push(rows[i]);
}
//Show progress bar ticker
document.getElementById("progress").style.display = "block";
/**
* Show the progress bar ticker animation
*
* @param pix The current pixel count to set the <div> margin at.
*/
function updateTicker(pix) {
var tick = document.getElementById("progressTicker");
document.getElementById("progressText").style.display = "block";
document.getElementById("progressText").innerHTML = "Sorting table...please wait";
if(dir == "right") {
if(pix < 170) {
pix += 5;
tick.style.marginLeft = pix + "px";
} else {
dir = "left";
}
} else {
if(pix > 0) {
pix -= 5;
tick.style.marginLeft = pix + "px";
} else {
dir = "left";
}
}
interval = window.setTimeout( function () { updateTicker(pix); }, 25);
}
updateTicker(pix);
/**
* Checks to see if a value is numeric.
*
* @param n The ining value to check.
* @return bool TRUE if value is numeric, FALSE otherwise.
*/
isNumeric = function (n) {
var num = false;
if(!isNaN(n) && isFinite(n)) {
num = true;
}
return num;
}
/**
* Compares two values and determines which one is "bigger".
*
* @param x A reference value to check against.
* @param y The value to be determined bigger or smaller than the reference.
* @return TRUE if y is greater or equal to x, FALSE otherwise
*/
function pare(x, y) {
var bigger = false;
x = x.cells[ndx].textContent;
y = y.cells[ndx].textContent;
//console.log(e.id);
if(isNumeric(x) && isNumeric(y)) {
if(y >= x) {
bigger = (e.id == "asc") ? true : false;
} else {
bigger = (e.id == "desc") ? true : false;
}
} else {
if(y.localeCompare(x) >= 0) {
bigger = (e.id == "asc") ? true : false;
} else {
bigger = (e.id == "desc") ? true : false;
}
}
return bigger;
}
/**
* Performs a quicksort O(n log n) on an array.
*
* @param array The array that needs sorting
* @return array The sorted array.
*/
function nlognSort(array) {
runs++
if(array.length > 1) {
var big = new Array();
var small = new Array();
var pivot = array.pop();
var l = array.length;
for(i = 0; i < l; i++) {
if(pare(pivot,array[i])) {
big.push(array[i]);
} else {
small.push(array[i]);
}
}
return Array.prototype.concat(nlognSort(small), pivot, nlognSort(big));
} else {
return array;
}
}
//Run sort routine
b = nlognSort(a);
//Rebuild <tbody> and replace new with the old
var tbody = document.createElement("tbody");
var l = b.length;
for(i = 0; i < l; i++) {
tbody.appendChild(b.shift());
}
parent.removeChild(document.getElementById("replace"));
parent.appendChild(tbody);
tbody.setAttribute("id","replace");
setTimeout(function () {
document.getElementById("progress").style.display = "none";
document.getElementById("progressText").style.display = "none";
clearTimeout(interval);
},1500);
}
window.onload = function() {
initHeaders(tableID);
}
Thanks again everyone!!
Share Improve this question edited May 23, 2017 at 11:46 CommunityBot 11 silver badge asked Jul 30, 2013 at 21:32 CrackertasticCrackertastic 4,9132 gold badges32 silver badges40 bronze badges 5-
1
At first I'd try to get a faster sort by using the native
Array::sort
withO(n log n)
, your current algorithm hasO(n²)
. Only if that doesn't help, you would have to write your own fast and asynchronous sort function (which seems a little over your head, judged from the current code quality). – Bergi Commented Jul 30, 2013 at 21:37 - Don't sort the DOM in-place. While JavaScript itself can sort quite fast, DOM access can be quite slow, especially on older browsers! – Hallvar Helleseth Commented Jul 30, 2013 at 21:39
- it's just too slow to both rearrange and update a progress bar. you might trying setting visibility:hidden on the table while sorting, that can avoid redraws, and greatly speed up the operation under certain conditions. – dandavis Commented Jul 30, 2013 at 21:40
- @Bergi Thanks for the tip about the sorting. A look around the internet and wikipedia gave me the info I needed to write up what is hopefully a good implementation of the quick sort. On a side note, I am still getting myself familiar with JS and what goes on under the hood, could you elaborate on what you meant about the current code quality? I didn't take offense to the ment, but was curious if there was something unorthodox I was/am doing. jsfiddle/jnBmp/5 – Crackertastic Commented Aug 1, 2013 at 6:11
- @HallvarHelleseth Thanks for the info about DOM access. I didn't realize how slow editing the DOM directly could be, and how shoddy looking rearranging rows would be in a loop. – Crackertastic Commented Aug 1, 2013 at 6:15
2 Answers
Reset to default 12Take a look at the following:
http://jsfiddle/6JxQk/
The idea here is to replace your for loop with an asynchronous loop that uses setTimeout()
, so you would go from the following:
for (var i = 0; i < rows; i++) {
// do stuff
}
... to this:
var i = 0;
(function doSort() {
// update progress
// do stuff
i++;
if (i < rows) {
setTimeout(doSort, 0);
}
})();
Although as you can see, this significantly slows down your sorting routine because in addition to updating the progress bar, this will reorder the rows of your table. With this in mind I think you are better off just using a built-in sort rather than your own implementation, and dropping the progress bar.
It may not be exactly what you are looking for - IMHO a progress bar must be used when you have an estimate of how much time a particular operation is going to take or how many bytes need to be transferred. In other non-deterministic cases you must be showing a spinner :-)