[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