[Mapbender-commits] r1694 - trunk/mapbender/http/javascripts

svn_mapbender at osgeo.org svn_mapbender at osgeo.org
Tue Oct 2 08:39:45 EDT 2007


Author: christoph
Date: 2007-10-02 08:39:45 -0400 (Tue, 02 Oct 2007)
New Revision: 1694

Added:
   trunk/mapbender/http/javascripts/mod_tab.js
Log:
class based refactoring

Added: trunk/mapbender/http/javascripts/mod_tab.js
===================================================================
--- trunk/mapbender/http/javascripts/mod_tab.js	                        (rev 0)
+++ trunk/mapbender/http/javascripts/mod_tab.js	2007-10-02 12:39:45 UTC (rev 1694)
@@ -0,0 +1,409 @@
+// check element vars
+try{
+	if (open_tab){
+		open_tab = Number(open_tab);
+
+		if (isNaN(open_tab)) {
+			var e = new Mb_warning("mod_tab.js: tab_init: open_tab must be a number or an empty string.");
+		}
+	}
+}
+catch(e){
+	var e = new Mb_warning("mod_tab.js: tab_init: open_tab is not set.");
+	open_tab = "";
+}
+
+var tabs;
+
+mb_registerInitFunctions('tab_init()');
+
+function tab_init(){
+	var obj = document.getElementById("tabs").style;
+
+	// generate a new tab array
+	tabs = new VerticalTabArray(tab_style);
+
+	// add the tabs from element vars
+	for (var i = 0; i < tab_ids.length; i++){
+		tabs.addTab(tab_ids[i], tab_prefix + tab_titles[i], tab_frameHeight[i]);
+	}
+
+	if (open_tab !== "") {
+		tabs.activateTab(tabs.get(open_tab).module);
+	}
+}
+
+/**
+ * @class A single vertical tab
+ * 
+ * @constructor
+ * @param {String} id the ID of the GUI element that will be displayed within the tab
+ * @param {String} title the header of the tab
+ * @param {Integer} frameHeight the height of the frame containing the GUI element
+ * @param {Integer} tabWidth the width of a tab (NOT the frame)
+ * @param {Integer} tabHeight the height of a tab (NOT the frame)
+ * @param {String} tabStyle A string with a CSS (example: position:absolute;visibility:visible;border: 1px solid white;font-size:12;color:#343434;background-color:#CFD2D4;cursor:pointer;)
+ * @param {Integer} number the index of the current tab in a {@link VerticalTabArray}.
+ */
+var VerticalTab = function (id, title, frameHeight, tabWidth, tabHeight, tabStyle, number) {
+	
+	/**
+	 * Sets the attributes of the tabs DOM node.
+	 * 
+	 * @private
+	 * @param {String} title the header of the tab
+	 * @param {Integer} frameHeight the height of the frame containing the GUI element
+	 * @param {Integer} tabWidth the width of a tab (NOT the frame)
+	 * @param {Integer} tabHeight the height of a tab (NOT the frame)
+	 * @param {String} tabStyle A string with a CSS (example: position:absolute;visibility:visible;border: 1px solid white;font-size:12;color:#343434;background-color:#CFD2D4;cursor:pointer;)
+	 * @param {Integer} number the index of the current tab in a {@link VerticalTabArray}.
+	 * 
+	 */
+	var setNodeAttributes = function(title, frameHeight, tabWidth, tabHeight, tabStyle, number) {
+	
+		node.id = "tabs_" + that.module;
+		
+		//set css class
+		node.className = "verticalTabs";
+
+		//mandatory style entries
+		node.style.position = "absolute";
+		node.style.width = tabWidth;
+		node.style.height = tabHeight;
+		node.style.top = number * tabHeight;
+		
+		// open or close on click
+		// see http://www.mapbender.org/index.php/Add_events_via_DOM_in_IE_and_FF
+		if (top.ie) {
+		   node.onclick = function() {
+		      var x = new Function ("", "tabs.activateTab('"+that.module+"');"); 
+		      x(); 
+		   };
+		}
+		else {
+			node.setAttribute("onclick", "tabs.activateTab('"+that.module+"');");
+		}
+		
+		// tab header
+		node.innerHTML = title;
+	};
+
+	/**
+	 * Returns the DOM node of this tab.
+	 *
+	 * @return the DOM node of this tab.
+	 * @type DOMNode
+	 */
+	this.getNode = function() {
+		return node;
+	};
+	
+	/**
+	 * The ID of the GUI element that will be displayed within the tab.
+	 */
+	this.module = id;
+
+	/**
+	 * The height of the frame containing the GUI element.
+	 */
+	this.height = frameHeight;
+	
+	/**
+	 * While a tab is opened or closed, the value is false.
+	 */
+	this.animationFinished = true;
+
+	/**
+	 * The DOM node of this tab.
+	 *
+	 * @private
+	 */
+	var node = document.createElement("div");
+	var that = this;
+	
+	setNodeAttributes(title, frameHeight, tabWidth, tabHeight, tabStyle, number);
+};
+	
+/**
+ * An array of vertical tabs, behaving like an accordion
+ *
+ * @extends List
+ * @param {String} cssString A string with a CSS (example: position:absolute;visibility:visible;border: 1px solid white;font-size:12;color:#343434;background-color:#CFD2D4;cursor:pointer;)
+ */	
+var VerticalTabArray = function (cssString) {
+	
+	/**
+	 * Adds a new tab to the Array.
+	 *
+	 * @param {String} id the ID of the GUI element that will be displayed within the tab
+	 * @param {String} title the header of the tab
+	 * @param {Integer} height the height of the frame containing the GUI element
+	 */
+	this.addTab = function(id, title, height) {
+		var tab = new VerticalTab(id, title, height, tabWidth, tabHeight, tabStyle, this.count());
+		this.add(tab);
+
+		document.getElementById(id).style.visibility = 'hidden';
+
+		// append the new tab
+		rootNode.appendChild(this.get(-1).getNode());
+	};
+	
+	/**
+	 * Removes a tab from the Array.
+	 *
+	 * @param {String} id the ID of the GUI element within the tab.
+	 */
+	this.delTab = function(id) {
+		var index = getIndexById(id);
+		
+		if (index !== null) {
+			// delete the DOM node
+			rootNode.removeChild(this.get(index).getNode());
+
+			// delete the tab
+			this.del(index);
+			
+			// move the other tabs (below the removed tab) up
+			for (var i = index; i < this.count(); i++) {
+				var currentNode = this.get(i).getNode();
+				
+				// parseInt removes "px"
+				var currentTop = parseInt(currentNode.style.top);
+				currentNode.style.top = currentTop - tabHeight;
+			}			
+		}
+	};
+	
+	/**
+	 * Opens a tab specified by the module Id.
+	 *
+	 * @param {String} id the ID of the GUI element within the tab.
+	 */
+	this.activateTab = function(id) {
+		// if no tab is currently opening or closing
+		if (isAnimationFinished()) {
+		
+			for (var i=0; i < this.count(); i++) {
+				hideFrame(this.get(i).module)
+			}
+		
+			// if the opened tab is the active tab, close it
+			if (id === activeTabId) {
+				closeTab(activeTabId);
+			}
+			//otherwise
+			else {
+				// show the desired tab
+				openTab(id);
+			}
+		}
+		else {
+			var e = new Mb_warning("mod_tab.js: could not activate tab, opening or closing in progress!");
+		}
+	};
+
+	/**
+	 * Animated opening and closing of the tab with the given id.
+	 * Needs to be public because it is called via "setInterval". 
+	 *
+	 * @param {String} openOrClose a string with the values "open" or "close".
+	 */
+	this.animate = function(openOrClose) {
+
+		for (var i=0; i < this.count(); i++) {
+			
+			if (this.get(i).animationFinished === false) {
+
+				//The 'top' position of the i-th tab after the animation
+				var currentTabNewTop = i * tabHeight;
+	
+				if (openOrClose == 'open') {
+					var indexOfOpeningTab = getIndexById(activeTabId);
+					
+					// move the lower tabs down by the height of the opening tab
+					if (indexOfOpeningTab !== null && i > indexOfOpeningTab) {
+						currentTabNewTop += this.get(indexOfOpeningTab).height;
+					}
+				}	
+				//The current 'top' position of the i-th tab
+				//(parseInt removes 'px')
+				var currentTabCurrentTop = parseInt(this.get(i).getNode().style.top);
+				
+				// animation is finished
+				if (currentTabCurrentTop == currentTabNewTop) {
+					this.get(i).animationFinished = true;
+				}	
+				// animation not yet finished, move the tab down
+				else if (currentTabCurrentTop < currentTabNewTop) {
+					var pixel = Math.min(pixelPerIteration, currentTabNewTop - currentTabCurrentTop);
+					this.get(i).getNode().style.top = currentTabCurrentTop + pixel;
+				}
+				// animation not yet finished, move the tab up
+				else if (currentTabCurrentTop > currentTabNewTop) {
+					var pixel = Math.min(pixelPerIteration, currentTabCurrentTop - currentTabNewTop);
+					this.get(i).getNode().style.top = currentTabCurrentTop - pixel;
+				}
+				else {
+					var e = new Mb_exception("mod_tab.js: animate: unknown state for tab "+ i + " (currentTop: "+currentTabCurrentTop+", newTop:"+currentTabNewTop+")");
+				}
+			}
+		}
+		// check if the animation is finished
+		if (isAnimationFinished()) {
+			stopAnimation();
+			if (openOrClose == "open") {
+				showFrame(activeTabId);
+			}
+		}
+	};
+
+	/**
+	 * Returns the index of the vertical tab with a given id 
+	 *
+	 * @private
+	 * @param {String} id the ID of the GUI element within the tab.
+	 */
+	var getIndexById = function(id) {
+		for (var i = 0; i < that.count(); i++) {
+			if (that.get(i).module == id) {
+				return i;
+			}
+		}
+		var e = new Mb_exception("mod_tab.js: getIndexById: ID '"+id+"' not found.");
+		return null;
+	};
+	
+	/**
+	 * Closes a tab.
+	 * 
+	 * @private
+	 * @param {String} id the ID of the GUI element within the tab.
+	 */
+	var closeTab = function(id) {
+		if (id !== null) {
+			hideFrame(id);
+			activeTabId = null;
+			startAnimation("close");
+		}		
+	};
+	
+	/**
+	 * Opens a tab.
+	 *
+	 * @private
+	 * @param {String} id the ID of the GUI element within the tab.
+	 */
+	var openTab = function(id) {
+		if (id !== null) {
+			activeTabId = id;
+			startAnimation("open");
+		}
+	};
+
+	/**
+	 * Hides a frame within a tab (before closing the tab).
+	 *
+	 * @private
+	 * @param {String} id the ID of the GUI element within the tab.
+	 */
+	var hideFrame = function(id) {
+		var index = getIndexById(id);
+		if (index !== null) {
+			var obj = document.getElementById(id).style;
+			obj.visibility = 'hidden';
+		}
+	};
+	
+	/**
+	 * Shows a frame within a tab (after opening the tab).
+	 *
+	 * @private
+	 * @param {String} id the ID of the GUI element within the tab.
+	 */
+	var showFrame = function(id) {
+		var index = getIndexById(id);
+		if (index !== null) {
+			var obj = document.getElementById(id).style;
+			var newpos = ((index+1) * tabHeight) + parseInt(tabTopOffset);
+			obj.top = (newpos + 1) + "px";
+			obj.left = (tabLeftOffset) + "px";
+			obj.width = tabWidth;
+			obj.height = (parseInt(that.get(index).height) - 2);
+			obj.visibility = 'visible';
+		}
+	};
+
+	/**
+	 * Starts the animation of the opening and closing tabs
+	 *
+	 * @private
+	 * @param {String} openOrClose a string with the values "open" or "close".
+	 */
+	var startAnimation = function(openOrClose) {
+		for (var i = 0; i < that.count(); i++) {
+			that.get(i).animationFinished = false;
+		}
+		tabInterval = setInterval("tabs.animate('"+openOrClose+"')",1);
+	};
+	
+	/**
+	 * Checks if the animation of the opening and closing tabs is finished.
+	 *
+	 * @private
+	 */
+	var isAnimationFinished = function() {
+		for (var i = 0; i < that.count(); i ++) {
+			if (that.get(i).animationFinished === false) {
+				return false;
+			}
+		}
+		return true;
+	};
+
+	/**
+	 * Stops the animation of the opening and closing tabs
+	 *
+	 * @private
+	 */
+	var stopAnimation = function() {
+		clearInterval(tabInterval);		
+	};
+
+	this.list = [];
+	var that = this;
+
+	/**
+	 * The DOM node of the tab array.
+	 */
+	var rootNode = document.getElementById("tabs");
+
+	/**
+	 * The ID of the currently open tab. If no tab is open, the value is NULL
+	 */
+	var activeTabId = null;
+
+	/**
+	 * Number of pixel that a tab moves while opening or closing.
+	 * @private
+	 */
+	var pixelPerIteration = 20;
+	
+	/**
+	 * Used for the 'setInterval' call of 'this.animate'
+	 */
+	var tabInterval;
+
+
+	var tabTopOffset = parseInt(rootNode.style.top);
+	var tabLeftOffset = parseInt(rootNode.style.left);
+	var tabWidth = parseInt(rootNode.style.width);
+	var tabHeight = parseInt(rootNode.style.height);
+	var tabStyle = cssString;
+
+	
+	var styleObj = new StyleTag();
+	styleObj.addClass("verticalTabs", tabStyle);
+};
+
+VerticalTabArray.prototype = new List();
\ No newline at end of file



More information about the Mapbender_commits mailing list