[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