[icinga-checkins] icinga.org: icinga-web/jmosshammer/default: * Sliding tabs to reorder cronks by drag'n drop

git at icinga.org git at icinga.org
Tue Apr 13 17:49:37 CEST 2010


Module: icinga-web
Branch: jmosshammer/default
Commit: 088be685b26abcae0624ca21ec8b797c96b1ebd7
URL:    https://git.icinga.org/?p=icinga-web.git;a=commit;h=088be685b26abcae0624ca21ec8b797c96b1ebd7

Author: Marius Hein <marius.hein at netways.de>
Date:   Fri Apr  9 13:49:09 2010 +0200

* Sliding tabs to reorder cronks by drag'n drop

---

 app/config/icinga.xml                              |    1 +
 .../Cronks/templates/System/CronkPortalSuccess.php |   76 ++--------
 lib/appkit/js/ext/slidingtabs.js                   |  165 ++++++++++++++++++++
 3 files changed, 178 insertions(+), 64 deletions(-)

diff --git a/app/config/icinga.xml b/app/config/icinga.xml
index a0a6231..0d297b0 100644
--- a/app/config/icinga.xml
+++ b/app/config/icinga.xml
@@ -153,6 +153,7 @@
 			<parameter>%core.root_dir%/lib/appkit/js/ext/ExtJs.js</parameter>
 			<parameter>%core.root_dir%/lib/appkit/js/ext/ScriptDynaLoader.js</parameter>
 			<parameter>%core.root_dir%/lib/appkit/js/ext/FancyTextField.js</parameter>
+			<parameter>%core.root_dir%/lib/appkit/js/ext/slidingtabs.js</parameter>
 			<parameter>%core.root_dir%/lib/appkit/js/SimpleDataProvider.js</parameter>
 			<parameter>%core.root_dir%/lib/appkit/js/ext/FilterHandler.js</parameter>
 
diff --git a/app/modules/Cronks/templates/System/CronkPortalSuccess.php b/app/modules/Cronks/templates/System/CronkPortalSuccess.php
index dde6bf6..69c867d 100644
--- a/app/modules/Cronks/templates/System/CronkPortalSuccess.php
+++ b/app/modules/Cronks/templates/System/CronkPortalSuccess.php
@@ -7,73 +7,21 @@
 
 Ext.onReady(function() {
 
-var TabDragOrder = function() {
-	var tp = null;
-	
-	TabDragOrder.superclass.constructor.call(this);
-}
-
-TabDragOrder = (new (Ext.extend(TabDragOrder, Ext.util.Observable, {
-	init : function(p) {
-		tp = p;
-		
-		tp.on('render', this.initDD, this, { single: true });
-		
-		tp.on('add', function(panel, item, index) { this.addDraggable(item) }, this);
-	},
+var SlidingTabs = (new(Ext.extend(Object, {
 	
-	initDD : function() {
-		this.dropTarget = (new (Ext.extend(Ext.dd.DropTarget, {
-			notifyDrop : function(source, e, data) {
-				var te = e.getTarget('li.x-tab-strip-closable');
-				var d = Ext.dd.Registry.getTarget(te);
-				if (d && "id" in d) {
-					var tab = Ext.getCmp(d.id);
-					if (tab && source.tab) {
-						
-						var index = tp.items.findIndex('id', tab.getId());
-						if (index > 0) {
-							(function() {
-								var re = tp.remove(source.tab, false);
-								var a = tp.getActiveTab();
-								tp.insert(index, re);
-								tp.setActiveTab(a);
-								
-							}).defer(40, this);
-						}
-						
-					}
-				}
-			}
-		}))(tp.el, { ddGroup: 'cronk-tab-panels' }));
+	init: function(tabpanel){
+		tabpanel.initTab = tabpanel.initTab.createSequence(this.initTab,tabpanel);
 	},
 	
-	addDraggable : function(ele) {
-		var de = tp.getTabEl(ele);
-		if (de) {
-			
-			Ext.dd.Registry.register(de, { id: ele.getId() } );
-			
-			ele.dd = (new (Ext.extend (Ext.dd.DragSource, {
-				init: function() {
-					Ext.dd.DD.prototype.init.apply(this, arguments);
-					this.setYConstraint(0,0);
-					this.tab = ele;
-				},
-				
-				onStartDrag : function(x, y) {
-					// tp.hideTabStripItem(ele);
-				},
-				
-				endDrag : function(e) {
-					// tp.unhideTabStripItem(ele);
-				},
-				
-				
-			}))(de, { ddGroup: 'cronk-tab-panels' }))
-		}
+	initTab: function(item, index){
+		var p = this.getTemplateArgs(item);
+		if(!this.slidingTabsID) this.slidingTabsID = Ext.id(); // Create a unique ID for this tabpanel
+		new Ext.ux.DDSlidingTab(p, this.slidingTabsID, {
+			tabpanel:this // Pass a reference to the tabpanel for each dragObject
+		});
 	}
-})));
+	
+}))()); 
 
 var CronkTabPlugin = (new (function() {
 
@@ -269,7 +217,7 @@ var tabPanel = new Ext.TabPanel({
 	resizeTabs : false,
 	
 	// Plugin
-	plugins: [CronkTabPlugin, TabDragOrder],
+	plugins: [CronkTabPlugin, SlidingTabs],
 	
 	// This component is stateful!
 	stateful: true,
diff --git a/lib/appkit/js/ext/slidingtabs.js b/lib/appkit/js/ext/slidingtabs.js
new file mode 100644
index 0000000..c500a55
--- /dev/null
+++ b/lib/appkit/js/ext/slidingtabs.js
@@ -0,0 +1,165 @@
+/*

+ * By Jake Knerr - Copyright 2010 - supersonicecho at gmail.com

+ * 

+ * Version 1.0

+ * 

+ * LICENSE

+ * GPL v3

+ * 

+ */

+ 

+Ext.ux.SlidingTabPanel = Ext.extend(Ext.TabPanel, {

+	

+	initTab: function(item, index){

+		Ext.ux.SlidingTabPanel.superclass.initTab.call(this, item, index);

+		var p = this.getTemplateArgs(item);

+		if(!this.slidingTabsID) this.slidingTabsID = Ext.id(); // Create a unique ID for this tabpanel

+		new Ext.ux.DDSlidingTab(p, this.slidingTabsID, {

+			tabpanel:this // Pass a reference to the tabpanel for each dragObject

+		});

+	}

+	

+});

+

+Ext.ux.DDSlidingTab = Ext.extend(Ext.dd.DDProxy, {

+	

+	// Constructor

+	constructor: function() {

+		Ext.ux.DDSlidingTab.superclass.constructor.apply(this, arguments);

+		this.setYConstraint(0,0,0); // Lock the proxy to its initial Y coordinate

+		

+		// Create a convenient reference to the tab's tabpanel

+		this.tabpanel = this.config.tabpanel;

+		

+		// Set the slide duration

+		this.slideDuration = this.tabpanel.slideDuration;

+		if(!this.slideDuration) this.slideDuration = .1;

+	}

+	

+	// Pseudo Private Methods

+	,handleMouseDown: function(e, oDD){

+		if(this.primaryButtonOnly && e.button != 0) return;

+		if(this.isLocked()) return;

+		this.DDM.refreshCache(this.groups);

+		var pt = new Ext.lib.Point(Ext.lib.Event.getPageX(e), Ext.lib.Event.getPageY(e));

+		if (!this.hasOuterHandles && !this.DDM.isOverTarget(pt, this) )  {

+		} else {

+			if (this.clickValidator(e)) {

+				this.setStartPosition(); // Set the initial element position

+				this.b4MouseDown(e);

+				this.onMouseDown(e);

+				this.DDM.handleMouseDown(e, this);

+				// this.DDM.stopEvent(e); // Must remove this event swallower for the tabpanel to work

+			}

+		}

+	}

+	,startDrag: function(x, y) {

+		Ext.dd.DDM.useCache = false; // Disable caching of element location

+		Ext.dd.DDM.mode = 1; // Point mode

+		

+		this.proxyWrapper = Ext.get(this.getDragEl()); // Grab a reference to the proxy element we are creating

+		this.proxyWrapper.update(); // Clear out the proxy's nodes

+		this.proxyWrapper.applyStyles('z-index:1001;border:0 none;');

+		this.proxyWrapper.addClass('tab-proxy');

+			

+			// Use 2 nested divs to mimic the default tab styling

+			// You may need to customize the proxy to get it to look like your custom tabpanel if you use a bunch of custom css classes and styles

+		this.stripWrap = this.proxyWrapper.insertHtml('afterBegin', '<div class="x-tab-strip x-tab-strip-top"></div>', true);

+		this.dragEl = this.stripWrap.insertHtml('afterBegin','<div></div>', true);

+		

+		this.tab = Ext.get(this.getEl()); // Grab a reference to the tab being dragged

+		this.tab.applyStyles('visibility:hidden;'); // Hide the tab being dragged

+		

+		// Insert the html and css classes for the dragged tab into the proxy

+		this.dragEl.insertHtml('afterBegin', this.tab.dom.innerHTML, false);

+		this.dragEl.dom.className = this.tab.dom.className; 

+		

+		// Constrain the proxy drag in the X coordinate to the tabpanel

+		var panelWidth = this.tabpanel.el.getWidth();

+		var panelX = this.tabpanel.el.getX();

+		var tabX = this.tab.getX();

+		var tabWidth = this.tab.getWidth();

+		var left = tabX - panelX;

+		var right = panelX + panelWidth - tabX - tabWidth;

+		this.resetConstraints();

+		this.setXConstraint(left, right);

+	}

+	,onDragOver: function(e, targetArr) {

+		e.stopEvent();

+		

+		// Grab the tab you have dragged the proxy over

+		var target = Ext.get(targetArr[0].id);

+		var targetWidth = target.getWidth();

+		var targetX = target.getX();

+		var targetMiddle = targetX + (targetWidth / 2);

+		var elX = this.tab.getX();

+		var dragX = this.proxyWrapper.getX();

+		var dragW = this.proxyWrapper.getWidth();

+		if(dragX < targetX && ((dragX + dragW) > targetMiddle) ) {

+			if(target.next() != this.tab) {

+				target.applyStyles('visibility:hidden;');

+				this.tab.insertAfter(target);

+				this.targetProxy = this.createSliderProxy(targetX, target);

+				if(!this.targetProxy.hasActiveFx()) this.animateSliderProxy(target, this.targetProxy, elX);

+			}

+		}

+		if(dragX > targetX && (dragX < targetMiddle)  ) {

+			if(this.tab.next() != target) {

+				target.applyStyles('visibility:hidden;');

+				this.tab.insertBefore(target);

+				this.targetProxy = this.createSliderProxy(targetX, target);

+				if(!this.targetProxy.hasActiveFx()) this.animateSliderProxy(target, this.targetProxy, elX);

+			}

+		}

+	}

+	,animateSliderProxy: function(target, targetProxy, elX){

+		targetProxy.shift({

+			x: elX

+			,easing: 'easeOut'

+			,duration: this.slideDuration

+			,callback: function() {

+				targetProxy.remove();

+				target.applyStyles('visibility:visible;');

+			}

+			,scope:this

+		}); 

+	}

+	,createSliderProxy: function(targetX, target) {

+		var sliderWrapperEl = Ext.getBody().insertHtml('afterBegin', '<div class="tab-proxy" style="position:absolute;visibility:visible;z-index:999;left:' + targetX + 'px;"></div>', true);

+		sliderWrapperEl.stripWrapper = sliderWrapperEl.insertHtml('afterBegin', '<div class="x-tab-strip x-tab-strip-top"></div>', true);

+		sliderWrapperEl.dragEl = sliderWrapperEl.stripWrapper.insertHtml('afterBegin', '<div></div>', true);

+		sliderWrapperEl.dragEl.update(target.dom.innerHTML);

+		sliderWrapperEl.dragEl.dom.className = target.dom.className;

+		var h = parseInt(target.getTop(false));

+		sliderWrapperEl.setTop(h)

+		return sliderWrapperEl;

+	}

+	,onDragDrop: function(e, targetId) {

+		e.stopEvent();

+	}

+	,endDrag: function(e){

+		var elX 		= this.tab.getX();

+		this.proxyWrapper.applyStyles('visibility:visible;');

+		

+		// Animate the dragProxy to the proper position

+		this.proxyWrapper.shift({

+			x: elX

+			,easing: 'easeOut'

+			,duration: this.slideDuration

+			,callback: function() {

+				this.proxyWrapper.applyStyles('visibility:hidden;');

+				this.tab.applyStyles('visibility:visible;');

+				

+				// Cleanup

+				this.stripWrap.remove();

+				this.dragEl.remove();

+				if(!this.targetProxy) return;

+				this.targetProxy.stripWrapper.remove();

+				this.targetProxy.dragEl.remove();

+			}

+			,scope:this

+		});

+		

+		Ext.dd.DDM.useCache = true;

+	}

+});
\ No newline at end of file





More information about the icinga-checkins mailing list