473,418 Members | 2,052 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,418 software developers and data experts.

Javascript - sequence of events

Hi,

I am working with a table sorting script which can be found here
http://www.workingwith.me.uk/article..._table_sorting
This script works very nicely, but when there is a large amount of data
to sort e.g > 200 then there is a slight delay in the table sort. To
cater for this I want to provide some feedback to the user to inform
them that the sort function is processing. My idea is to add a
"sorting...." message to the top right of the page, much the same as
the 'loading' message in gmail.
To do this I am dynamically creating a div element and adding it to the
document.body
I do this as part of the onclick event that triggers the table sort.

My problem is, eventhough I create and append the 'sorting...' element
at the start of the onclick event (before the sorting is done), the
element only gets added after the sorting is complete?

I cant seem to get the 'sorting..' element to be added to the page
while the sorting is in progress. Does javascript execute things in a
sequence that prevents me adding my element to the page?
Interestingly, I can execute a javascript alert and this gets displayed
before the sorting begins.....why would
document.body.appendChild(myDiv) not?

Hopefully someone has come across this before and can help. I've added
my HTML and javascript below.

Thank you,

Chris

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>Table Sorter Proof of Concept</title>

<link rel="stylesheet" href="style.css" type="text/css" />

<script type='text/javascript' src='common.js'></script>
<script type='text/javascript' src='css.js'></script>
<script type='text/javascript'
src='standardista-table-sorting.js'></script>
</head>
<body>
<table class='sortable autostripe'>
<thead>
<tr>
<th>Heading</th>
<th>Heading</th>
<th>Heading</th>
<th>Heading</th>
<th>Heading</th>
<th>Heading</th>
<th>Heading</th>
<th>Heading</th>
</tr>
</thead>
<tbody>
<script>
for (var i=0; i < 500; i++) {

var number = Math.round(Math.random()*1000);

var day = (1 + Math.round(Math.random()*30));
if (day < 10) {
day = '0' + day;
}
var month = (1 + Math.round(Math.random()*11));
if (month < 10) {
month = '0' + month;
}
var year = (1990 + Math.round(Math.random()*16));

var pennies = (1 + Math.round(Math.random()*99));
if (pennies < 10) {
pennies = '0' + pennies;
}

var pounds = (1 + Math.round(Math.random()*1500));

var date = day + '/' + month + '/' + year;

document.write("<tr>");
document.write("<td>"+number+"</td>");
document.write("<td>"+date+"</td>");
document.write("<td>$"+pounds+'.'+pennies+"</td>");
document.write("<td>"+number+"</td>");
document.write("<td>"+date+"</td>");
document.write("<td>$"+pounds+'.'+pennies+"</td>");
document.write("<td>"+number+"</td>");
document.write("<td>"+date+"</td>");
document.write("</tr>");
}
</script>
</tbody>
</table>

</body>
</html>

/**
* Written by Neil Crosby.
*
http://www.workingwith.me.uk/article..._table_sorting
*
* This module is based on Stuart Langridge's "sorttable" code.
Specifically,
* the determineSortFunction, sortCaseInsensitive, sortDate,
sortNumeric, and
* sortCurrency functions are heavily based on his code. This module
would not
* have been possible without Stuart's earlier outstanding work.
*
* Use this wherever you want, but please keep this comment at the top
of this file.
*
* Copyright (c) 2006 Neil Crosby
*
* Permission is hereby granted, free of charge, to any person
obtaining a copy
* of this software and associated documentation files (the
"Software"), to deal
* in the Software without restriction, including without limitation
the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell
* copies of the Software, and to permit persons to whom the Software
is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE
* SOFTWARE.
**/
var standardistaTableSorting = {

that: false,
isOdd: false,

sortColumnIndex : -1,
lastAssignedId : 0,
newRows: -1,
lastSortedTable: -1,

/**
* Initialises the Standardista Table Sorting module
**/
init : function() {
// first, check whether this web browser is capable of running this
script
if (!document.getElementsByTagName) {
return;
}

this.that = this;

this.run();

},

/**
* Runs over each table in the document, making it sortable if it has
a class
* assigned named "sortable" and an id assigned.
**/
run : function() {
var tables = document.getElementsByTagName("table");

for (var i=0; i < tables.length; i++) {
var thisTable = tables[i];

if (css.elementHasClass(thisTable, 'sortable')) {
this.makeSortable(thisTable);
}
}
},

/**
* Makes the given table sortable.
**/
makeSortable : function(table) {

// first, check if the table has an id. if it doesn't, give it one
if (!table.id) {
table.id = 'sortableTable'+this.lastAssignedId++;
}

// if this table does not have a thead, we don't want to know about
it
if (!table.tHead || !table.tHead.rows || 0 ==
table.tHead.rows.length) {
return;
}

// we'll assume that the last row of headings in the thead is the row
that
// wants to become clickable
var row = table.tHead.rows[table.tHead.rows.length - 1];

for (var i=0; i < row.cells.length; i++) {

// create a link with an onClick event which will
// control the sorting of the table
var linkEl = createElement('a');
linkEl.href = '#';
linkEl.onclick = this.headingClicked;
linkEl.setAttribute('columnId', i);
linkEl.title = 'Click to sort';

// move the current contents of the cell that we're
// hyperlinking into the hyperlink
var innerEls = row.cells[i].childNodes;
for (var j = 0; j < innerEls.length; j++) {
linkEl.appendChild(innerEls[j]);
}

// and finally add the new link back into the cell
row.cells[i].appendChild(linkEl);

var spanEl = createElement('span');
spanEl.className = 'tableSortArrow';
spanEl.appendChild(document.createTextNode('\u00A0 \u00A0'));
row.cells[i].appendChild(spanEl);

}

if (css.elementHasClass(table, 'autostripe')) {
this.isOdd = false;
var rows = table.tBodies[0].rows;

// We appendChild rows that already exist to the tbody, so it moves
them rather than creating new ones
for (var i=0;i<rows.length;i++) {
this.doStripe(rows[i]);
}
}
},

headingClicked: function(e) {

showDialog();
var that = standardistaTableSorting.that;

// linkEl is the hyperlink that was clicked on which caused
// this method to be called
var linkEl = getEventTarget(e);

// directly outside it is a td, tr, thead and table
var td = linkEl.parentNode;
var tr = td.parentNode;
var thead = tr.parentNode;
var table = thead.parentNode;

// if the table we're looking at doesn't have any rows
// (or only has one) then there's no point trying to sort it
if (!table.tBodies || table.tBodies[0].rows.length <= 1) {
return false;
}

// the column we want is indicated by td.cellIndex
var column = linkEl.getAttribute('columnId') || td.cellIndex;
//var column = td.cellIndex;

// find out what the current sort order of this column is
var arrows = css.getElementsByClass(td, 'tableSortArrow', 'span');
var previousSortOrder = '';
if (arrows.length > 0) {
previousSortOrder = arrows[0].getAttribute('sortOrder');
}

// work out how we want to sort this column using the data in the
first cell
// but just getting the first cell is no good if it contains no data
// so if the first cell just contains white space then we need to
track
// down until we find a cell which does contain some actual data
var itm = ''
var rowNum = 0;
while ('' == itm && rowNum < table.tBodies[0].rows.length) {
itm =
that.getInnerText(table.tBodies[0].rows[rowNum].cells[column]);
rowNum++;
}
var sortfn = that.determineSortFunction(itm);

// if the last column that was sorted was this one, then all we need
to
// do is reverse the sorting on this column
if (table.id == that.lastSortedTable && column ==
that.sortColumnIndex) {
newRows = that.newRows;
newRows.reverse();
// otherwise, we have to do the full sort
} else {
that.sortColumnIndex = column;
var newRows = new Array();

for (var j = 0; j < table.tBodies[0].rows.length; j++) {
newRows[j] = table.tBodies[0].rows[j];
}

newRows.sort(sortfn);
}

that.moveRows(table, newRows);
that.newRows = newRows;
that.lastSortedTable = table.id;

// now, give the user some feedback about which way the column is
sorted

// first, get rid of any arrows in any heading cells
var arrows = css.getElementsByClass(tr, 'tableSortArrow', 'span');
for (var j = 0; j < arrows.length; j++) {
var arrowParent = arrows[j].parentNode;
arrowParent.removeChild(arrows[j]);

if (arrowParent != td) {
spanEl = createElement('span');
spanEl.className = 'tableSortArrow';
spanEl.appendChild(document.createTextNode('\u00A0 \u00A0'));
arrowParent.appendChild(spanEl);
}
}

// now, add back in some feedback
var spanEl = createElement('span');
spanEl.className = 'tableSortArrow';
if (null == previousSortOrder || '' == previousSortOrder || 'DESC' ==
previousSortOrder) {
spanEl.appendChild(document.createTextNode(' \u2191'));
spanEl.setAttribute('sortOrder', 'ASC');
} else {
spanEl.appendChild(document.createTextNode(' \u2193'));
spanEl.setAttribute('sortOrder', 'DESC');
}

td.appendChild(spanEl);

return false;
},

getInnerText : function(el) {

if ('string' == typeof el || 'undefined' == typeof el) {
return el;
}

if (el.innerText) {
return el.innerText; // Not needed but it is faster
}

var str = el.getAttribute('standardistaTableSortingInnerText ');
if (null != str && '' != str) {
return str;
}
str = '';

var cs = el.childNodes;
var l = cs.length;
for (var i = 0; i < l; i++) {
// 'if' is considerably quicker than a 'switch' statement,
// in Internet Explorer which translates up to a good time
// reduction since this is a very often called recursive function
if (1 == cs[i].nodeType) { // ELEMENT NODE
str += this.getInnerText(cs[i]);
break;
} else if (3 == cs[i].nodeType) { //TEXT_NODE
str += cs[i].nodeValue;
break;
}
}

// set the innertext for this element directly on the element
// so that it can be retrieved early next time the innertext
// is requested
el.setAttribute('standardistaTableSortingInnerText ', str);

return str;
},

determineSortFunction : function(itm) {

var sortfn = this.sortCaseInsensitive;

if (itm.match(/^\d\d[\/-]\d\d[\/-]\d\d\d\d$/)) {
sortfn = this.sortDate;
}
if (itm.match(/^\d\d[\/-]\d\d[\/-]\d\d$/)) {
sortfn = this.sortDate;
}
if (itm.match(/^[£$]/)) {
sortfn = this.sortCurrency;
}
if (itm.match(/^\d?\.?\d+$/)) {
sortfn = this.sortNumeric;
}
if (itm.match(/^[+-]?\d*\.?\d+([eE]-?\d+)?$/)) {
sortfn = this.sortNumeric;
}
if
(itm.match(/^([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])$/))
{
sortfn = this.sortIP;
}

return sortfn;
},

sortCaseInsensitive : function(a, b) {
var that = standardistaTableSorting.that;

var aa =
that.getInnerText(a.cells[that.sortColumnIndex]).toLowerCase();
var bb =
that.getInnerText(b.cells[that.sortColumnIndex]).toLowerCase();
if (aa==bb) {
return 0;
} else if (aa<bb) {
return -1;
} else {
return 1;
}
},

sortDate : function(a,b) {
var that = standardistaTableSorting.that;

// y2k notes: two digit years less than 50 are treated as 20XX,
greater than 50 are treated as 19XX
var aa = that.getInnerText(a.cells[that.sortColumnIndex]);
var bb = that.getInnerText(b.cells[that.sortColumnIndex]);

var dt1, dt2, yr = -1;

if (aa.length == 10) {
dt1 = aa.substr(6,4)+aa.substr(3,2)+aa.substr(0,2);
} else {
yr = aa.substr(6,2);
if (parseInt(yr) < 50) {
yr = '20'+yr;
} else {
yr = '19'+yr;
}
dt1 = yr+aa.substr(3,2)+aa.substr(0,2);
}

if (bb.length == 10) {
dt2 = bb.substr(6,4)+bb.substr(3,2)+bb.substr(0,2);
} else {
yr = bb.substr(6,2);
if (parseInt(yr) < 50) {
yr = '20'+yr;
} else {
yr = '19'+yr;
}
dt2 = yr+bb.substr(3,2)+bb.substr(0,2);
}

if (dt1==dt2) {
return 0;
} else if (dt1<dt2) {
return -1;
}
return 1;
},

sortCurrency : function(a,b) {
var that = standardistaTableSorting.that;

var aa =
that.getInnerText(a.cells[that.sortColumnIndex]).replace(/[^0-9.]/g,'');
var bb =
that.getInnerText(b.cells[that.sortColumnIndex]).replace(/[^0-9.]/g,'');
return parseFloat(aa) - parseFloat(bb);
},

sortNumeric : function(a,b) {
var that = standardistaTableSorting.that;

var aa =
parseFloat(that.getInnerText(a.cells[that.sortColumnIndex]));
if (isNaN(aa)) {
aa = 0;
}
var bb =
parseFloat(that.getInnerText(b.cells[that.sortColumnIndex]));
if (isNaN(bb)) {
bb = 0;
}
return aa-bb;
},

makeStandardIPAddress : function(val) {
var vals = val.split('.');

for (x in vals) {
val = vals[x];

while (3 > val.length) {
val = '0'+val;
}
vals[x] = val;
}

val = vals.join('.');

return val;
},

sortIP : function(a,b) {
var that = standardistaTableSorting.that;

var aa =
that.makeStandardIPAddress(that.getInnerText(a.cel ls[that.sortColumnIndex])..toLowerCase());
var bb =
that.makeStandardIPAddress(that.getInnerText(b.cel ls[that.sortColumnIndex])..toLowerCase());
if (aa==bb) {
return 0;
} else if (aa<bb) {
return -1;
} else {
return 1;
}
},

moveRows : function(table, newRows) {
this.isOdd = false;

// We appendChild rows that already exist to the tbody, so it moves
them rather than creating new ones
for (var i=0;i<newRows.length;i++) {
var rowItem = newRows[i];

this.doStripe(rowItem);

table.tBodies[0].appendChild(rowItem);
}
},

doStripe : function(rowItem) {
if (this.isOdd) {
css.addClassToElement(rowItem, 'odd');
} else {
css.removeClassFromElement(rowItem, 'odd');
}

this.isOdd = !this.isOdd;
}

}

function standardistaTableSortingInit() {
standardistaTableSorting.init();
}

addEvent(window, 'load', standardistaTableSortingInit)

function showDialog(){

var shortcutsDiv = document.createElement('DIV');
shortcutsDiv.id = 'shortcutsDivId';
//Esc will lose focus and close it. Need an input field to focus on.
with (shortcutsDiv.style) {
display = "block";
position = "fixed";
visibility = "visible";
top = "8%";
left = "41%";
margin = "0 10% 0 10%";
width = "30%";
textAlign = "center";
MozBorderRadius = "10px";
padding = "10px";
color = "#000";
background = "#EE8800";

zIndex = 1000;
}
shortcutsDiv.innerHTML = 'sorting';
document.body.appendChild(shortcutsDiv);

}

Jun 4 '06 #1
4 6289
bb******@gmail.com said the following on 6/4/2006 3:13 PM:
Hi,

I am working with a table sorting script which can be found here
http://www.workingwith.me.uk/article..._table_sorting
This script works very nicely, but when there is a large amount of data
to sort e.g > 200 then there is a slight delay in the table sort. To
cater for this I want to provide some feedback to the user to inform
them that the sort function is processing. My idea is to add a
"sorting...." message to the top right of the page, much the same as
the 'loading' message in gmail.
To do this I am dynamically creating a div element and adding it to the
document.body
I do this as part of the onclick event that triggers the table sort.

My problem is, eventhough I create and append the 'sorting...' element
at the start of the onclick event (before the sorting is done), the
element only gets added after the sorting is complete?

I cant seem to get the 'sorting..' element to be added to the page
while the sorting is in progress. Does javascript execute things in a
sequence that prevents me adding my element to the page?
Interestingly, I can execute a javascript alert and this gets displayed
before the sorting begins.....why would
document.body.appendChild(myDiv) not?
Hopefully someone has come across this before and can help. I've added
my HTML and javascript below.


<FAQENTRY>
Why doesn't the display get updated when doing time intensive calculations?
</FAQENTRY>
It is a very well known about issue where the UA doesn't get updated
visibly until the function executes. The alert causes a delay so the
display gets updated.

The solution? Call a setTimeout to a second function.

function dummyFunction(){
//create the message here
window.setTimeout(realFunction,60)
}

function realFunction(){
//sort the table

//remove the message when sorting is finished.
}

--
Randy
comp.lang.javascript FAQ - http://jibbering.com/faq & newsgroup weekly
Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/
Jun 4 '06 #2
That worked great thanks. I had to changed the JS around a bit, but the
setTimeout worked perfectly.

Thanks,

Chris

Jun 4 '06 #3
That worked thanks. I had to change my JS slightly but the setTimeout
worked perfectly.

Thanks,

Chris

Jun 4 '06 #4
JRS: In article <11**********************@i40g2000cwc.googlegroups .com>
, dated Sun, 4 Jun 2006 12:13:35 remote, seen in
news:comp.lang.javascript, bb******@gmail.com posted :

One should seek and read a newsgroup FAQ, and read the group for a
while, before posting to the group.

Had you done so, you would probably have realised that posted code
should be executable as received, and therefore that you should not
permit your posting agent to line-wrap it; and, partly to help there,
you should replace tab-indenting with indenting by 2-3 spaces.
Math.round(Math.random()...) is rarely good, though it may not matter
in this case - see FAQ 4.22 - OTOH, your "pennies" range looks like
1..100.

parseInt(yr) should normally have a second parameter, though in this
case it probably does not matter; however, unary + would be better (and
maybe can be used instead of parseFloat too).

If you use a function, rather than a string of code, as the first
parameter of setTimeout, it may not always work.

Note for future reference FAQ 2.3 para 7.

--
© John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 IE 4 ©
<URL:http://www.jibbering.com/faq/> JL/RC: FAQ of news:comp.lang.javascript
<URL:http://www.merlyn.demon.co.uk/js-index.htm> jscr maths, dates, sources.
<URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/jscr/&c, FAQ items, links.
Jun 5 '06 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

25
by: Martin Walke | last post by:
Hi, This may seem like a client side problem but.... I have web pages that are made up of a number of javascript include files as well as 'in page' script. They all work fine running locally...
2
by: Stephan Parrot | last post by:
Hello people! I have a really weird problem here... Let's say i have 4 lines of codes in a function like this one: SomeSVGDialog.Show(); //this is an SVG dialog box that shows to give some...
1
by: teb | last post by:
Hello all, Here is basically the situation. I have an empty div on my page. When I mouseover a word, the innerHTML of the div gets written with a table. The td elements all have onclick,...
1
by: Robains | last post by:
I'm using a TextBox_Leave event to trigger the saving of a value to my object, however, my object is created via the AfterSelect from a TreView control -- which is fine. BUT, the problem seems...
1
by: SammyBar | last post by:
Hi all, I'm having troubles with a Symbol 9000 device (Compact Framework v 1.1) when activating the barcode scanner from a window. The problem is related to the Activated event of the form which...
7
by: David Thielen | last post by:
You would think this list exists but I can’t find it anywhere. Is this the correct order for these events to be called? Global.asax Application_Start (only once) Global.asax Application_Init...
0
by: ajloren123 | last post by:
I´ve been working over the EPCM.subscribeEvent I´ve included all the raised events collected from the javascripts. The completed code looks like this: //Subscribe the events from portal ...
1
by: Jordan S. | last post by:
I'm just wondering if this would work. Please note that I'm not asking *how* to raise events. I'm clear on that. What I'm not clear on is the sequence in which events are raised by custom controls...
1
by: swethak | last post by:
hi, i have a code to disply the calendar and add events to that. It works fine.But my requirement is to i have to disply a weekly and daily calendar.Any body plz suggest that what modifications i...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.