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

svn_mapbender at osgeo.org svn_mapbender at osgeo.org
Fri Apr 23 05:40:15 EDT 2010


Author: christoph
Date: 2010-04-23 05:40:15 -0400 (Fri, 23 Apr 2010)
New Revision: 6017

Added:
   trunk/mapbender/http/javascripts/mod_tab_expandable.js
Modified:
   trunk/mapbender/http/javascripts/mod_tab.php
Log:
new element var

php_var

expandable 0/1

expands the tabs so they fit the document vertically

Modified: trunk/mapbender/http/javascripts/mod_tab.php
===================================================================
--- trunk/mapbender/http/javascripts/mod_tab.php	2010-04-23 09:36:39 UTC (rev 6016)
+++ trunk/mapbender/http/javascripts/mod_tab.php	2010-04-23 09:40:15 UTC (rev 6017)
@@ -41,6 +41,11 @@
 $output = $json->encode($tab_ids);
 
 echo "var tab_ids = " . $output . ";";	
-
-include(dirname(__FILE__) . "/mod_tab.js");
+echo "console.log('e = " . $expandable . "');";
+if (!isset($expandable) || !$expandable) {
+	include(dirname(__FILE__) . "/mod_tab.js");
+}
+else {
+	include(dirname(__FILE__) . "/mod_tab_expandable.js");
+}
 ?>
\ No newline at end of file

Added: trunk/mapbender/http/javascripts/mod_tab_expandable.js
===================================================================
--- trunk/mapbender/http/javascripts/mod_tab_expandable.js	                        (rev 0)
+++ trunk/mapbender/http/javascripts/mod_tab_expandable.js	2010-04-23 09:40:15 UTC (rev 6017)
@@ -0,0 +1,554 @@
+// 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 z = new Mb_warning("mod_tab.js: tab_init: open_tab is not set.");
+    open_tab = "";
+}
+
+var tabs;
+
+eventLocalize.register(function(){
+    localizeTabs();
+});
+
+eventInit.register(function(){
+    tab_init();
+    localizeTabs();
+});
+
+function localizeTabs(){
+    mb_ajax_json("../php/mod_tab_messages.php", function(obj, status){
+        tabs.setTitles(obj);
+    });
+}
+
+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.openTab(tabs.get(open_tab).module);
+    }
+}
+
+function tab_open(elementName){
+    // show the desired tab
+    tabs.openTab(elementName);
+}
+
+/**
+ * @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 ui-widget-header";
+        
+        //mandatory style entries
+        node.style.position = "absolute";
+        node.style.width = tabWidth;
+        node.style.height = tabHeight;
+        node.style.top = number * tabHeight;
+        
+        this.originalHeight = tabHeight;
+        
+        // open or close on click
+        // see http://www.mapbender.org/index.php/Add_events_via_DOM_in_IE_and_FF
+        if ($.browser.msie) {
+        
+            node.onclick = function(){
+                tabs.toggleTab(that.module);
+            };
+        }
+        else {
+            node.onclick = function(){
+                tabs.toggleTab(that.module);
+            };
+        }
+        
+        // tab header
+        node.innerHTML = title;
+    };
+    
+    this.top = function(){
+        var o = $(node).offset();
+        return parseInt(o.top, 10);
+    };
+    
+    
+    /**
+     * 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;
+    
+    this.originalHeight;
+    
+    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';
+        document.getElementById(id).style.display = 'none';
+        
+        // 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, 10);
+                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.toggleTab = 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
+                activeTabId = id;
+                startAnimation("open");
+            }
+        }
+        else {
+            var e = new Mb_warning("mod_tab.js: could not activate tab, opening or closing in progress!");
+        }
+    };
+    
+    /**
+     * Sets the titles of each single tab after l10n
+     *
+     * @param {Object} obj an array containing objects with id and title
+     */
+    this.setTitles = function(obj){
+        for (var i = 0; i < this.count(); i++) {
+            for (var j = 0; j < obj.length; j++) {
+                if (this.get(i).module == obj[j].id) {
+                    this.get(i).getNode().innerHTML = tabPrefix + obj[j].title;
+                }
+            }
+        }
+    }
+    /**
+     * Returns the absolute coordinates of tab by the module ID
+     *
+     * @param {String} id the ID of the GUI element within the tab.
+     * @return {String} String with "left,top,right,bottom"
+     */
+    this.getCoords = function(id){
+        var coords = [];
+        //get indixes
+        if (activeTabId) {
+            var indexOfOpeningTab = getIndexById(activeTabId);
+        }
+        var index = getIndexById(id);
+        
+        //left
+        coords[0] = tabLeftOffset;
+        //top
+        coords[1] = tabTopOffset + index * tabHeight + (activeTabId && indexOfOpeningTab < index ? this.get(indexOfOpeningTab).height : 0);
+        //right
+        coords[2] = coords[0] + tabWidth;
+        //bottom
+        coords[3] = coords[1] + (id == activeTabId ? this.get(indexOfOpeningTab).height + tabHeight : tabHeight);
+        
+        return coords.join(",");
+    };
+    
+	var getWindowHeight = function () {
+		var dh = $(document).height();
+		var wh = $(window).height();
+		return wh > dh ? wh : dh;
+	};
+	
+    /**
+     * 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){
+        var height = getWindowHeight() - this.get(0).top();
+        
+        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) {
+                        var diff = height - this.count() * tabHeight - 2;
+                        var node = $("#" + this.get(indexOfOpeningTab).module);
+                        node.css("height", diff + "px");
+                        currentTabNewTop += diff;
+                    }
+                }
+                //The current 'top' position of the i-th tab
+                //(parseInt removes 'px')
+                var currentTabCurrentTop = parseInt(this.get(i).getNode().style.top, 10);
+                
+                // 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.
+     *
+     * @public
+     * @param {String} id the ID of the GUI element within the tab.
+     */
+    this.openTab = function(id){
+        if (id !== null && activeTabId != id) {
+            // if no tab is currently opening or closing
+            if (isAnimationFinished()) {
+                for (var i = 0; i < this.count(); i++) {
+                    hideFrame(this.get(i).module);
+                }
+            }
+            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);
+            obj.style.visibility = 'hidden';
+            obj.style.display = 'none';
+            //try to apply for childs of horizontal tabs
+            try {
+                if (obj.tabs) 
+                    document.getElementById(obj.tabs[obj.activeTab].id).style.visibility = 'hidden';
+                document.getElementById(obj.tabs[obj.activeTab].id).style.display = 'none';
+            } 
+            catch (e) {
+            }
+        }
+    };
+    
+    /**
+     * 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);
+            var newpos = ((index + 1) * tabHeight) + parseInt(tabTopOffset);
+            //try to apply for childs of horizontal tabs
+            try {
+                if (obj.tabs) {
+                    activeTab = document.getElementById(obj.tabs[obj.activeTab].id).style;
+                    activeTab.visibility = 'visible';
+                    activeTab.display = 'block';
+                    activeTab.top = ((newpos + 1) + obj.tab_height) + "px";
+                    activeTab.left = (tabLeftOffset) + "px";
+                    activeTab.width = tabWidth;
+                    var height = getWindowHeight() - that.get(0).top();
+                    var diff = height - that.count() * tabHeight - 2;
+                    activeTab.height = diff + "px";
+                    //(parseInt(that.get(index).height) - 2) - obj.tab_height;
+                }
+            } 
+            catch (e) {
+            }
+            obj = obj.style;
+            obj.top = (newpos + 1) + "px";
+            obj.left = (tabLeftOffset) + "px";
+            obj.width = tabWidth;
+            var height = getWindowHeight() - that.get(0).top();
+            var diff = height - that.count() * tabHeight - 4;
+            obj.height = diff + "px";
+            obj.visibility = 'visible';
+            obj.display = 'block';
+        }
+    };
+    
+    /**
+     * 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(function(){
+            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, 10);
+    var tabLeftOffset = parseInt(rootNode.style.left, 10);
+    var tabWidth = parseInt(rootNode.style.width, 10);
+    var tabHeight = parseInt(rootNode.style.height, 10);
+    var tabStyle = cssString;
+    
+    var tabPrefix = tab_prefix || '';
+    var styleObj = new StyleTag();
+    styleObj.addClass("verticalTabs", tabStyle);
+    
+    var resizeTabs = function(e){
+        var height = getWindowHeight() - that.get(0).top();
+        var diff = height - that.count() * tabHeight - 2;
+        var indexOfOpeningTab = getIndexById(activeTabId);
+        var node = that.get(indexOfOpeningTab);
+		if (node === undefined) {
+			return;
+		}
+		node = $("#" + node.module);
+        var oldHeight = parseInt(node.css("height"), 10);
+        node.css("height", diff + "px");
+        var previousTop = parseInt(that.get(indexOfOpeningTab).getNode().style.top, 10);
+        for (var i = indexOfOpeningTab + 1; i < that.count(); i++) {
+            var currentNode = that.get(i).getNode();
+            var oldTop = parseInt(currentNode.style.top, 10);
+            var newTop = oldTop + diff - oldHeight;
+            newTop = (newTop < previousTop + tabHeight) ? previousTop + tabHeight : newTop;
+            previousTop += tabHeight;
+            currentNode.style.top = newTop + "px";
+            
+        }
+    };
+    
+    $(window).resize(resizeTabs);
+};
+
+VerticalTabArray.prototype = new List();



More information about the Mapbender_commits mailing list