incubator-xap-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jmarga...@apache.org
Subject svn commit: r448446 - in /incubator/xap/trunk/src/xap/widgets/dojo: HorizontalPanel.js TreeTable.js VerticalPanel.js
Date Thu, 21 Sep 2006 03:13:43 GMT
Author: jmargaris
Date: Wed Sep 20 20:13:43 2006
New Revision: 448446

URL: http://svn.apache.org/viewvc?view=rev&rev=448446
Log:
don't use setAttribute() on created elements, bad in IE
table cleanup and improvements

Modified:
    incubator/xap/trunk/src/xap/widgets/dojo/HorizontalPanel.js
    incubator/xap/trunk/src/xap/widgets/dojo/TreeTable.js
    incubator/xap/trunk/src/xap/widgets/dojo/VerticalPanel.js

Modified: incubator/xap/trunk/src/xap/widgets/dojo/HorizontalPanel.js
URL: http://svn.apache.org/viewvc/incubator/xap/trunk/src/xap/widgets/dojo/HorizontalPanel.js?view=diff&rev=448446&r1=448445&r2=448446
==============================================================================
--- incubator/xap/trunk/src/xap/widgets/dojo/HorizontalPanel.js (original)
+++ incubator/xap/trunk/src/xap/widgets/dojo/HorizontalPanel.js Wed Sep 20 20:13:43 2006
@@ -14,6 +14,7 @@
 
 xap.widgets.dojo.HorizontalPanel = function(){
 	dojo.widget.HtmlWidget.call(this);
+	this.align = "start";
 }
 dojo.inherits(xap.widgets.dojo.HorizontalPanel, dojo.widget.HtmlWidget);
 
@@ -23,7 +24,6 @@
 	templateCssPath: null ,
 	widgetType: "HorizontalPanel",
 	isContainer: true,
-	align : "start",
 	
 	addChild: function(child, overrideContainerNode, pos, ref, insertIndex){
 		var row = this.endCell.parentNode;
@@ -31,13 +31,13 @@
 		
 		
 		if (this.align=="center"){
-			cell.setAttribute("valign", "center");
+			cell.vAlign  = center;
 		}
 		else if (this.align=="start"){
-			cell.setAttribute("valign", "top");
+			cell.vAlign  = "top";
 		}
 		else if (this.align=="end"){
-			cell.setAttribute("valign", "bottom");
+			cell.vAlign  = "bottom";
 		}
 		else if (this.align=="stretch"){
 			child.domNode.style.height="100%";

Modified: incubator/xap/trunk/src/xap/widgets/dojo/TreeTable.js
URL: http://svn.apache.org/viewvc/incubator/xap/trunk/src/xap/widgets/dojo/TreeTable.js?view=diff&rev=448446&r1=448445&r2=448446
==============================================================================
--- incubator/xap/trunk/src/xap/widgets/dojo/TreeTable.js (original)
+++ incubator/xap/trunk/src/xap/widgets/dojo/TreeTable.js Wed Sep 20 20:13:43 2006
@@ -6,29 +6,32 @@
 Xap.provide("xap.widgets.dojo.TableRow");
 Xap.provide("xap.widgets.dojo.TableCell");
 
-dojo.require("dojo.widget.*");
-dojo.require("dojo.widget.HtmlWidget");
-dojo.require("dojo.dom");
-dojo.require("dojo.html");
-dojo.require("dojo.style");
-dojo.require("dojo.event");
+Xap.require("dojo.widget.*");
+Xap.require("dojo.widget.HtmlWidget");
+Xap.require("dojo.dom");
+Xap.require("dojo.html");
+Xap.require("dojo.style");
+Xap.require("dojo.event");
 
 Xap.require("xap.widgets.dojo.ScrollPane");
+Xap.require("xap.util.ArrayHelper");
 
 dojo.widget.tags.addParseTreeHandler("dojo:TreeTable");
 dojo.widget.tags.addParseTreeHandler("dojo:TableColumn");
 dojo.widget.tags.addParseTreeHandler("dojo:TableRow");
 
 xap.widgets.dojo.TreeTable = function(){
-	this.columns = [];
+	this._columns = [];
 	
 	//top level rows only
-	this.rows = [];
-	this.validatePending = false;
-	this.sizeAdjustmentPending = false;
+	this._rows = [];
+	
+	this._rebuildTableTask = null;
+	this._resizeTableTask = null;
+	this._rebuildRowsTask = null;
 		
 	dojo.widget.HtmlWidget.call(this);
-	this._revalidate();
+	this._rebuildTableLater();
 }
 
 dojo.inherits(xap.widgets.dojo.TreeTable,xap.widgets.dojo.ScrollPane);
@@ -38,41 +41,96 @@
 	templateString: '<div style="padding:0px 0px 40px 0px;overflow:hidden;position:relative">'
+
 		'<table dojoAttachPoint="headerTable" style="position:relative;width:100%;table-layout:fixed"><tbody
dojoAttachPoint="headerTbody"><tr dojoAttachPoint="headerRow"></tr></tbody></table>'+
 		'<div dojoAttachPoint="scrollDiv" style="overflow:auto;width:100%;height:100%">'
+
-		'<table dojoAttachPoint="table"><tbody dojoAttachPoint="tbody"></tbody></table></div></div>',
+		'<table dojoAttachPoint="table"><tbody></tbody></table></div></div>',
 	templateCssPath: null ,
 	widgetType: "TreeTable",
 	isContainer: false,
 	
-	_revalidate: function(){
-		if (!this.validatePending){
-			this.validatePending = true;
-			dojo.lang.setTimeout(this, this._createTable, 0);
-			
+	
+	
+	
+	/**
+	 * 
+	 * 
+	 * Table layout/ resizing methods
+	 * 
+	 * 
+	 */
+
+	/**
+	 * Rebuild just the rows of the table, typically called after sorting.
+	 */
+	_rebuildRowsLater : function(){
+		
+		//if a full rebuild is pending don't bother
+		if (!this._rebuildTableTask && !this._rebuildRowsTask){
+			this._rebuildRowsTask = dojo.lang.setTimeout(this, this._rebuildRows, 0);		
 		}
 	},
 	
-	_adjustSizes: function(){
-		if (!this.sizeAdjustmentPending){
-			this.sizeAdjustmentPending = true;
-			dojo.lang.setTimeout(this, this._resizeTable, 0);
+	/**
+	 * Rebuilds the entire table from scratch, should be a very rare occurence.
+	 */
+	_rebuildTableLater: function(){
+		
+		//cancel any partial rebuild tasks
+		if (this._rebuildRowsTask){
+			window.clearTimeout(this._rebuildRowsTask);
+			this._rebuildRowsTask = null;
+		}
+		if (this._resizeTableTask ){
+			window.clearTimeout(this._resizeTableTask);
+			this._resizeTableTask = null;
+		}
+		
+		//if not already scheduled then schedule it
+		if (!this._rebuildTableTask){
+			this._rebuildTableTask = dojo.lang.setTimeout(this, this._rebuildTable, 0);
 		}
 	},
 	
+	/**
+	 * Once the table is built/sized run through 
+	 * and make sure headers and column widths agree
+	 */
+	_resizeTableLater: function(){
+		if (!this._resizeTableTask){
+			this._resizeTableTask = dojo.lang.setTimeout(this, this._resizeTable, 0);
+		}
+	},
+	
+	/**
+	 * After a table has been built to the screen go through and make sure
+	 * the widths of columns and headers match up.
+	 */
 	_resizeTable: function(){
+		
 		var finalWidths = [];
-		finalWidths[this.columns.length-1] = "";
+		finalWidths[this._columns.length-1] = "";
 		
 		var tableWidth = 0;
-		for (var i=0; i<this.columns.length;i++){
+		
+		var firstRow = this.tbody.childNodes[0];
+		for (var i=0; i<this._columns.length;i++){
+			
+			//We could ask for the width of the actual columns but
+			//IE just returns zero for those, so we use the first
+			//cell width instead
 			var headerWidth = this.headerRow.childNodes[i].offsetWidth;
-			var columnWidth = this.tbody.childNodes[0].childNodes[i].offsetWidth;
-			alert("Header width and main column width = " + headerWidth + "/" + columnWidth);
+			var columnWidth = 0;
+			
+			//we don't always have a first row or cells in the first row
+			//so be careful. Maybe we should enforce that row has the right number
+			//of <td> but some can be empty?
+			if (firstRow && firstRow.childNodes[i]){
+				columnWidth = firstRow.childNodes[i].offsetWidth;
+			}
 			var finalWidth = headerWidth>columnWidth ? headerWidth:columnWidth;
 			tableWidth += finalWidth;
 			finalWidths[i] = finalWidth + "px";
 		}
 		
-		for (var i=0; i<this.columns.length;i++){
+		for (var i=0; i<this._columns.length;i++){
 			this.headerTable.childNodes[i].style.width = finalWidths[i];
 			this.table.childNodes[i].style.width = finalWidths[i];
 		}
@@ -83,27 +141,16 @@
 		this.headerTable.style.tableLayout = "fixed";
 		this.table.style.tableLayout = "fixed";
 		
-		this.sizeAdjustmentPending = false;
+		window.clearTimeout(this._resizeTableTask);
+		this._resizeTableTask = null;
 	},
 	
-	_createTable: function(){
-		alert("create table");
-		this._rebuildTable();
-		this.validatePending = false;
-		this._adjustSizes();
-	},
-	
-	_rebuildTable: function(){
-		this.domNode.removeChild(this.headerTable);
+	/**
+	 * Rebuilds just the real table part of table, not
+	 * the headers.
+	 */
+	_rebuildBody: function(){
 		this.domNode.removeChild(this.scrollDiv);
-
-		this.headerTable = document.createElement("table");
-		this.domNode.appendChild(this.headerTable);
-		
-		this.headerTable.style.width="400px";
-		this.headerTable.style.position="relative";
-		this.headerTable.rules = "all";
-		
 		this.scrollDiv = document.createElement("div");
 		this.domNode.appendChild(this.scrollDiv);
 		
@@ -117,13 +164,54 @@
 		this.table.rules = "all";
 		
 		//populate cols under both tables
-		for (var i = 0; i<this.columns.length; i++){
-			var column = this.columns[i];
-			var headerCol = document.createElement("col");
-			this.headerTable.appendChild(headerCol);
+		for (var i = 0; i<this._columns.length; i++){
+			var column = this._columns[i];
 			var bodyCol = document.createElement("col");
 			this.table.appendChild(bodyCol);
 		}
+		this._rebuildRows();
+	},
+	
+	/**
+	 * Rebuilds only the rows in the table, leaving the columns in place
+	 * with the same sizes. Useful for sorting.
+	 */
+	_rebuildRows: function(){
+		if (this.tbody){
+			this.table.removeChild(this.tbody);
+		}
+		
+		this.tbody = document.createElement("tbody");
+		this.table.appendChild(this.tbody);
+		
+		//now populate the body rows
+		for (var i =0; i<this._rows.length; i++){
+			this._rebuildRow(this._rows[i], 0);
+		}
+		window.clearTimeout(this._rebuildRowsTask);
+		this._rebuildRowsTask = null;
+	},
+	
+	/**
+	 * Rebuilds just the head (column headers)
+	 * of the table.
+	 */
+	_rebuildHead: function(){
+		this.domNode.removeChild(this.headerTable);
+		this.headerTable = document.createElement("table");
+		this.domNode.appendChild(this.headerTable);
+		
+		
+		this.headerTable.style.width="400px";
+		this.headerTable.style.position="relative";
+		this.headerTable.rules = "all";
+		
+		//populate cols under both tables
+		for (var i = 0; i<this._columns.length; i++){
+			var column = this._columns[i];
+			var headerCol = document.createElement("col");
+			this.headerTable.appendChild(headerCol);
+		}
 		
 		this.headerBody = document.createElement("tbody");
 		this.headerTable.appendChild(this.headerBody);
@@ -131,20 +219,24 @@
 		//now populate the header row
 		this.headerRow = document.createElement("tr");
 		this.headerBody.appendChild(this.headerRow);
-		for (var i = 0; i<this.columns.length; i++){
+		for (var i = 0; i<this._columns.length; i++){
 			var cell = document.createElement("td");
 			this.headerRow.appendChild(cell);
-			if (this.columns[i]._header){	
-				cell.appendChild(this.columns[i]._header);
+			if (this._columns[i]._header){	
+				cell.appendChild(this._columns[i]._header);
 			}
 		}
-		
-		this.tbody = document.createElement("tbody");
-		this.table.appendChild(this.tbody);
-		//now populate the body rows
-		for (var i =0; i<this.rows.length; i++){
-			this._rebuildRow(this.rows[i], 0);
-		}
+	},
+	
+	/**
+	 * Rebuilds the entire table from scratch
+	 */
+	_rebuildTable: function(){		
+		this._rebuildHead();
+		this._rebuildBody();
+		window.clearTimeout(this._rebuildTableTask);
+		this._rebuildTableTask = null;
+		this._resizeTableLater();
 	},
 	
 	_rebuildRow: function( row, depth ){
@@ -155,52 +247,90 @@
 		}
 	},
 	
-	onscroll : function(event){
-		if (this.scrollDiv){
-			this.headerTable.style.left = -this.scrollDiv.scrollLeft + "px";
-		}
-	},
-
 	
+	/**
+	 * 
+	 * 
+	 * dynamic add/remove
+	 * 
+	 * 
+	 */
+	 
 	insertColumn: function(column, index){
 		column.setTable(this);
-		if (index&&index>=0){
-			this.columns.splice(index,0, column);
-		}
-		else{
-			this.columns.push(column);
-		}
-		this._revalidate();
+		xap.util.ArrayHelper.insertElementAt(this._columns,column,index);
+		
+		//TODO we should really be able to make this
+		//more efficient by inserting the column in place
+		this._rebuildTableLater();
+	},
+	
+	removeColumn: function(column){
+		xap.util.ArrayHelper.removeElement (this._columns,column);
+		//TODO efficiency
+		this._rebuildTableLater();
 	},
 	
 	//index here is relative to parent row?
 	insertRow: function(row, index){
 		row.setTable(this);
-		if (index&&index>=0){
-			this.rows.splice(index,0, row);
-		}
-		else{
-			this.rows.push(row);
-		}
+		xap.util.ArrayHelper.insertElementAt(this._rows,row,index);		
+		//call _rowAdded because row can have child rows
 		this._rowAdded(row);
 	},
 	
+	removeRow: function( row ){
+		xap.util.ArrayHelper.removeElement (this._rows,row);
+		this._rowRemoved(row);
+	},
+	
 	_rowAdded: function(row){
 		row.setTable(this);
+		
+		//recurse through all children
 		for (var i = 0; i<row._rows.length;i++){
 			this._rowAdded(row._rows[i]);
 		}
-		this._revalidate();
+		
+		//TODO we should be able to insert the row into the table
+		//at the right spot. Gets kind of tricky for nested rows and such,
+		//in that case you need to insert relative to a sibling
+		this._rebuildRowsLater();
+	},
+	
+	_rowRemoved: function(row){
+		
+		//recurse through all children
+		for (var i = 0; i<row._rows.length;i++){
+			this._rowRemoved(row._rows[i]);
+		}
+		
+		//TODO we should be able to insert the row into the table
+		//at the right spot. Gets kind of tricky for nested rows and such,
+		//in that case you need to insert relative to a sibling
+		this._rebuildRowsLater();
+	},
+
+
+	/**
+	 * 
+	 * Other junk
+	 * 
+	 */	
+	 
+	 
+	onscroll : function(event){
+		if (this.scrollDiv){
+			this.headerTable.style.left = -this.scrollDiv.scrollLeft + "px";
+		}
 	},
+
+
 	
 	//TODO PLACEHOLDER TEST CODE
 	sortColumn: function(){
-		this.rows.reverse();
-		
-		//when we do this what we really need to do is adjust the header
-		//icon and then rebuild ONLY the body, we don't need to rebuild
-		//the header row because that should remain constant.
-		this._revalidate();
+		this._rows.reverse();
+		this._rebuildRowsLater();
 	}
 	
 }
@@ -244,7 +374,6 @@
 	},
 	
 	onSort : function(){
-		alert("Sort a column!");
 		if (this._table){
 			this._table.sortColumn();
 		}
@@ -281,9 +410,17 @@
 		this._table = table;
 	},
 	
+	//right now cell is just a DomNode, not any sort of typed
+	//thing, it should probably have something like:
+	//getText() function, domNode, getSortValue() function, etc,
+	//right now we don't have a good way of knowing what the text is
 	addCell : function( cell ){
 		var td = document.createElement("td");
 		this.domNode.appendChild(td);
+		
+		//TODO should we use style.textAlign instead of this
+		//everywhere???
+		td.align="left";
 		if (!this._indentSpan){
 			this._indentSpan = document.createElement("span");
 			td.appendChild(this._indentSpan);
@@ -339,16 +476,10 @@
 	//if we set to invis, set all children to invis as well
 	//if we set it back, set children back ONLY if we are expanded!
 	setVisible : function (visible){
-		var visibility = visible ? "visible":"hidden";
-		
-		//IMPORTANT
-		//if you use static here on IE you can't click on the node
-		//afterwards sometimes. If you use relative you can but then
-		//scrolling gets messed up. It seems like jiggering the row a bit,
-		//for example by changing the height works. Need a good solution here
-		var position = visible ? "static":"absolute";
+		var visibility = visible ? "visible":"hidden";	
+		var display = visible ? "":"none";
 		this.domNode.style.visibility = visibility;
-		this.domNode.style.position = position;
+		this.domNode.style.display = display;
 		for (var i = 0; i<this._rows.length; i++){
 			if (!visible || this._expanded){
 				this._rows[i].setVisible(visible);
@@ -361,12 +492,7 @@
 	},
 	
 	insertRow: function(row, index){
-		if (index&&index>=0){
-			this._rows.splice(index,0, row);
-		}
-		else{
-			this._rows.push(row);
-		}
+		xap.util.ArrayHelper.insertElementAt(this._rows,row,index);
 		if (this._table){
 			this._table._rowAdded(row);
 		}
@@ -375,8 +501,7 @@
 		if (this._rows.length==1){
 			this._adjustImage();
 		}
-		//after inserting a row we need to add the row to the parent table
-		
+		//after inserting a row we need to add the row to the parent table	
 	}	
 	
 });

Modified: incubator/xap/trunk/src/xap/widgets/dojo/VerticalPanel.js
URL: http://svn.apache.org/viewvc/incubator/xap/trunk/src/xap/widgets/dojo/VerticalPanel.js?view=diff&rev=448446&r1=448445&r2=448446
==============================================================================
--- incubator/xap/trunk/src/xap/widgets/dojo/VerticalPanel.js (original)
+++ incubator/xap/trunk/src/xap/widgets/dojo/VerticalPanel.js Wed Sep 20 20:13:43 2006
@@ -14,6 +14,7 @@
 
 xap.widgets.dojo.VerticalPanel = function(){
 	dojo.widget.HtmlWidget.call(this);
+	this.align = "center";//start, center, end, stretch
 }
 dojo.inherits(xap.widgets.dojo.VerticalPanel, dojo.widget.HtmlWidget);
 
@@ -24,7 +25,6 @@
 	templateCssPath: null ,
 	widgetType: "VerticalPanel",
 	isContainer: true,
-	align: "center", //start, center, end, stretch
 	
 	addChild: function(child, overrideContainerNode, pos, ref, insertIndex){
 		//TODO if they have something like height=50%
@@ -32,13 +32,13 @@
 		var row = document.createElement("tr");
 		var cell = document.createElement("td");
 		if (this.align=="center"){
-			cell.setAttribute("align", "center");
+			cell.align = "center";
 		}
 		else if (this.align=="start"){
-			cell.setAttribute("align", "left");
+			cell.align = "left";
 		}
 		else if (this.align=="end"){
-			cell.setAttribute("align", "right");
+			cell.align = "right";
 		}
 		
 		//if they set the width again after this it won't really work



Mime
View raw message