...

View Full Version : Dynamically adding a DIV to document.body



bboyle18
06-04-2006, 09:00 PM
Hi,

I am working with a table sorting script which can be found here
http://www.workingwith.me.uk/articles/scripting/standardista_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>


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) {
//This is where I am adding the Div. This is the start of the sort function but it does not get added until the sorting is complete
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;
},
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);

}

vwphillips
06-04-2006, 09:33 PM
namically creating a div element and adding it to t

why such a difficult life you make???????


code the elemnt in the HTML Code and make visible and hidden as required

bboyle18
06-04-2006, 09:38 PM
Thanks for the reply. But this does not solve the issue.
From what I have read around the web, there is a known issue with JS that with intensive calculations the UI doesnt get updated straight away. Apparently, createing a timeout might help solve th issue?
Any thoughts on this?

Thanks,

Chris



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum