The Cache: Technology Expert's Forum
 
*
Welcome, Guest. Please login or register. September 16, 2019, 09:12:08 PM

Login with username, password and session length


Pages: [1]
  Print  
Author Topic: Browser-agnostic dynamic table generation and management  (Read 3587 times)
perkiset
Olde World Hacker
Administrator
Lifer
*****
Offline Offline

Posts: 10096



View Profile
« on: May 05, 2007, 02:20:06 PM »

One of the things that messed with me the most when starting to work with really dynamic pages in JS, was table generation. Consider this: when you create a table in HTML, you do so in a heriarchical fashion ie., table, tr, td etc.

So at first I was using DOM commands to create a table exactly the same way. Worked in FF and Safari perfectly.

But in IE I got nothing.

What I finally got to was that for it to always work perfectly, I had to start in the middle and work my way out - IE did not like me create a table, then putting a row in it, then putting a cell in that and attributing the cell... it wanted me to create the cell and attribute it, then attach that to a row, then attach that to a table. To say that I was pissed off would be a pretty major understatement.

So I wrote a class to handle it. This class you talke to functionally, and then it builds the table only when you finally want to place it on your page. You can build it in any way you like, because the elements of the table are not committed until you want to place it - so that it stays OK in IE. Additionally I found that attributing cells and divs and such is different in IE than the rest... so I wanted to be able to functionally attribute things and not worry about the browser. So I added an attribute function to the table and that handle it all nicely.

Essentially, you use it like this:
Code:
// there are four params on this constructor, padding, spacing, border and width -
// if you don't specify any it's 0, 0, 0, 100%
tObj = new tableManager();
var aRowReference = tObj.newRow(); // you don't HAVE to take the row reference, but if you want to attribute it helps
// note that you can do any number of attributes, just pass the object to be attributed as the first parm,
// then the attribute name and value as every other parm from then on
tObj.attribute(aRowReference, 'valign', 'middle', 'align', 'center', 'bgcolor', '#ff0000');
// you may put a row reference into this call if you want to (you don not need to go serially)
// or, as in this case, I am asking for a new cell on the current row (the last one created)
tObj.newCell();
tObj.newTextCell('This is the text for the cell', 'anOptionalClassName');
tObj.sizingGraphicURL = '/graphics/dot_clear.gif'; // this is actually the default URL
tObj.newSizingCell(10, 0, 0); // height, width, colspan - requires the existence of sizingGraphicURL
tObj.addTableTo(document.getElementById('theTargetElement'));

And here it is - please post here if you want more assistance with usage.

/p

Code:
// ----------------------------------------------------------- //
//                       Table Manager                         //
// ----------------------------------------------------------- //
// This object is used to manage the creation of tables - not that
// you'd really need it if it wasn't for IE's quirkiness...
function tableManager(cellPadding, cellSpacing, border, width)
{
this.clear();
if (cellPadding) { this.cellPadding = cellPadding; }
if (cellSpacing) { this.cellSpacing = cellSpacing; }
if (border) { this.border = border; }
if (width) { this.width = width; }
}
tableManager.prototype.clear = function()
{
this.cellPadding = 0;
this.cellSpacing = 0;
this.border = 0;
this.width = '100%';
this.sizingGraphicURL = '/graphics/dot_clear.gif';

this.currentRow = null;
this.currentCell = null;

this.isIE = ((document.all) && (document.getElementById));
if (this.isIE) {
this.mainNode = document.createElement('TBODY');
} else {
this.mainNode = document.createElement('TABLE');
}
}
tableManager.prototype.addTableTo = function(newOwner)
{
if (this.isIE)
{
var tableNode = document.createElement('TABLE');
this.attribute(tableNode, 'cellpadding', this.cellPadding, 'cellspacing', this.cellSpacing, 'border', this.border, 'width', this.width);
tableNode.appendChild(this.mainNode);
newOwner.appendChild(tableNode);
return tableNode;
} else {
this.attribute(this.mainNode, 'cellpadding', this.cellPadding, 'cellspacing', this.cellSpacing, 'border', this.border, 'width', this.width);
newOwner.appendChild(this.mainNode);
return this.mainNode;
}
}
tableManager.prototype.attribute = function(theNode)
{
for(var i=1; i<arguments.length; i+=2)
{
if (this.isIE) {
// NN2 attribute the object the old way...
switch(arguments[i].toLowerCase())
{
case 'align' : theNode.align = arguments[i+1]; break;
case 'bgcolor' : theNode.bgColor = arguments[i+1]; break;
case 'border' : theNode.border = arguments[i+1]; break;
case 'cellpadding' : theNode.cellPadding = arguments[i+1]; break;
case 'cellspacing' : theNode.cellSpacing = arguments[i+1]; break;
case 'class' : theNode.className = arguments[i+1]; break;
case 'colspan' : theNode.colSpan = arguments[i+1]; break;
case 'enctype' : theNode.encoding = arguments[i+1]; break;
case 'height' : theNode.height = arguments[i+1]; break;
case 'href' : theNode.setAttribute('href', arguments[i+1]); break;
case 'id' : theNode.id = arguments[i+1]; break;
case 'method' : theNode.method = arguments[i+1]; break;
case 'name' : theNode.name = arguments[i+1]; break;
case 'nowrap' : theNode.noWrap = 'nowrap'; break;
case 'onclick' : theNode['onclick'] = new Function(arguments[i+1]); break;
case 'onblur' : theNode['onblur'] = new Function(arguments[i+1]); break;
case 'onchange' : theNode['onchange'] = new Function(arguments[i+1]); break;
case 'onclick' : theNode['onclick'] = new Function(arguments[i+1]); break;
case 'ondblclick' : theNode['ondblclick'] = new Function(arguments[i+1]); break;
case 'onfocus' : theNode['onfocus'] = new Function(arguments[i+1]); break;
case 'onkeypress' : theNode['onkeypress'] = new Function(arguments[i+1]); break;
case 'onmouseover' : theNode['onmouseover'] = new Function(arguments[i+1]); break;
case 'onmouseout' : theNode['onmouseout'] = new Function(arguments[i+1]); break;
case 'rowspan' : theNode.rowSpan = arguments[i+1]; break;
case 'size' : theNode.size = arguments[i+1]; break;
case 'src' : theNode.src = arguments[i+1]; break;
case 'type' : theNode.setAttribute('type', arguments[i+1]); break;
case 'valign' : theNode.vAlign = arguments[i+1]; break;
case 'value' : theNode.value = arguments[i+1]; break;
case 'visibility' : theNode.visibility = arguments[i+1]; break;
case 'width' : theNode.width = arguments[i+1]; break;
}
} else { theNode.setAttribute(arguments[i], arguments[i+1]); }
}
return theNode;
}
tableManager.prototype.newCell = function(rowNode)
{
if (!rowNode) { rowNode = this.currentRow; }
if (!rowNode) { rowNode = this.newRow(); }
this.currentCell = document.createElement('TD');
rowNode.appendChild(this.currentCell);
return this.currentCell;
}
tableManager.prototype.newCellContent = function(cellContent, rowNode)
{
if (!rowNode) { rowNode = this.currentRow; }
this.newCell();
this.currentCell.appendChild(cellContent);
return this.currentCell;
}
tableManager.prototype.newFirstCell = function(content)
{
this.newRow();
this.newCell();
if (content) { this.currentCell.appendChild(content); }
return this.currentCell;
}
tableManager.prototype.newRow = function()
{
this.currentRow = document.createElement('TR');
this.mainNode.appendChild(this.currentRow);
return this.currentRow;
}
tableManager.prototype.newTextCell = function(theText, theClass)
{
return this.textCell(theText, theClass);
}
tableManager.prototype.sizingCell = function(height, width, colSpan) { return this._sizingCell(this.currentRow, height, width, colSpan); }
tableManager.prototype._sizingCell = function(theRow, height, width, colSpan)
{
if (!theRow) { theRow = this.newRow(); }
var thisContent = document.createElement('img');
thisContent.src = this.sizingGraphicURL;
this.attribute(thisContent, 'height', height, 'width', width);
this.newCell(theRow).appendChild(thisContent);

if (colSpan) { this.attribute(this.currentCell, 'colSpan', colSpan); }
return this.currentCell;
}
tableManager.prototype.sizingRow = function(height, colSpan)
{
this.newRow();
this.sizingCell(height, 1, colSpan);
return this.currentCell;
}
tableManager.prototype.textCell = function(theText, textClass)
{
this.newCell();
if (textClass) { this.attribute(this.currentCell, 'class', textClass); }
this.currentCell.appendChild(document.createTextNode(theText));
return this.currentCell;
}
Logged

It is now believed, that after having lived in one compound with 3 wives and never leaving the house for 5 years, Bin Laden called the U.S. Navy Seals himself.
Pages: [1]
  Print  
 
Jump to:  

Perkiset's Place Home   Best of The Cache   phpMyIDE: MySQL Stored Procedures, Functions & Triggers
Politics @ Perkiset's   Pinkhat's Perspective   
cache
mart
coder
programmers
ajax
php
javascript
Powered by MySQL Powered by PHP Powered by SMF 1.1.2 | SMF © 2006-2007, Simple Machines LLC
Seo4Smf v0.2 © Webmaster's Talks


Valid XHTML 1.0! Valid CSS!