diff --git a/modules/admin/tpl/js/menu_setup.js b/modules/admin/tpl/js/menu_setup.js
index f85ef04ec..5c429f160 100644
--- a/modules/admin/tpl/js/menu_setup.js
+++ b/modules/admin/tpl/js/menu_setup.js
@@ -46,3 +46,180 @@ jQuery(function($){
});
});
+// menu - drag and drop
+jQuery(function($){
+
+var
+ dragging = false,
+ $holder = $('
');
+
+$('div.adminMenu')
+ .delegate('li:not(.placeholder,.parent)', {
+ 'mousedown.st' : function(event) {
+ var $this, $uls, $ul, width, height, offset, position, offsets, i, dropzone, wrapper='';
+
+ if($(event.target).is('a,input,label,textarea') || event.which != 1) return;
+
+ dragging = true;
+
+ $this = $(this);
+ height = $this.height();
+ width = $this.width();
+ $uls = $this.parentsUntil('.siteMap').filter('ul');
+ $ul = $uls.eq(-1);
+
+ $ul.css('position', 'relative');
+
+ position = {x:event.pageX, y:event.pageY};
+ offset = getOffset(this, $ul.get(0));
+
+ $clone = $this.clone(true).attr('target', true);
+
+ for(i=$uls.length-1; i; i--) {
+ $clone = $clone.wrap('').parent().parent();
+ }
+
+ // get offsets of all list-item elements
+ offsets = [];
+ $ul.find('li').each(function(idx) {
+ if($this[0] === this || $this.has(this).length) return true;
+
+ var o = getOffset(this, $ul.get(0));
+ offsets.push({top:o.top, bottom:o.top+32, $item:$(this)});
+ });
+
+ // Remove unnecessary elements from the clone, set class name and styles.
+ // Append it to the list
+ $clone
+ .find('.side,input').remove().end()
+ .addClass('draggable')
+ .css({
+ position: 'absolute',
+ opacity : .6,
+ width : width,
+ height : height,
+ left : offset.left,
+ top : offset.top,
+ zIndex : 100
+ })
+ .appendTo($ul.eq(0));
+
+ // Set a place holder
+ $holder
+ .css({
+ position:'absolute',
+ opacity : .6,
+ width : width,
+ height : '10px',
+ left : offset.left,
+ top : offset.top,
+ zIndex :99
+ })
+ .appendTo($ul.eq(0));
+
+ $this.css('opacity', .6);
+
+ $(document)
+ .unbind('mousemove.st mouseup.st')
+ .bind('mousemove.st', function(event) {
+ var diff, nTop, item, i, c, o;
+
+ dropzone = null;
+
+ diff = {x:position.x-event.pageX, y:position.y-event.pageY};
+ nTop = offset.top - diff.y;
+
+ for(i=0,c=offsets.length; i < c; i++) {
+ o = offsets[i];
+ if(o.top > nTop || o.bottom < nTop) continue;
+
+ dropzone = {element:o.$item};
+ if(o.$item.hasClass('parent')) {
+ dropzone.state = 'prepend';
+ $holder.css('top', o.bottom-5);
+ } else if(o.top > nTop - 12) {
+ dropzone.state = 'before';
+ $holder.css('top', o.top-5);
+ } else {
+ dropzone.state = 'after';
+ $holder.css('top', o.bottom-5);
+ }
+ }
+
+ $clone.css({top:nTop});
+ })
+ .bind('mouseup.st', function(event) {
+ var $dropzone, $li;
+
+ dragging = false;
+
+ $(document).unbind('mousemove.st mouseup.st');
+ $this.css('opacity', '');
+ $clone.remove();
+ $holder.remove();
+
+ // dummy list item for animation
+ $li = $('').height($this.height());
+
+ if(!dropzone) return;
+ $dropzone = $(dropzone.element);
+
+ $this.before($li);
+
+ if(dropzone.state == 'prepend') {
+ if(!$dropzone.find('>ul').length) $dropzone.find('>.side').after('');
+ $dropzone.find('>ul').prepend($this.hide());
+ } else {
+ $dropzone[dropzone.state]($this.hide());
+ }
+
+ $this.slideDown(100, function(){ $this.removeClass('active') });
+ $li.slideUp(100, function(){ var $par = $li.parent(); $li.remove(); if(!$par.children('li').length) $par.remove() });
+ });
+
+ return false;
+ },
+ 'mouseover.st' : function() {
+ if(!dragging) $(this).addClass('active');
+ return false;
+ },
+ 'mouseout.st' : function() {
+ if(!dragging) $(this).removeClass('active');
+ return false;
+ }
+ })
+ .find('li')
+ .prepend('')
+ .filter('.parent')
+ .find('>button.moveTo').css({'visibility':'hidden','margin-left':'-12px'}).end()
+ .end()
+ .end()
+
+$('')
+ .css({display:'none',position:'absolute',backgroundColor:'#000',opacity:0.7})
+ .appendTo('body');
+
+function getOffset(elem, offsetParent) {
+ var top = 0, left = 0;
+
+ while(elem && elem != offsetParent) {
+ top += elem.offsetTop;
+ left += elem.offsetLeft;
+
+ elem = elem.offsetParent;
+ }
+
+ return {top:top, left:left};
+}
+
+function setHolder(info, yPos) {
+ if(Math.abs(info.top-yPos) <= 10) {
+ $holder.css({top:info.top-10,height:'10px'});
+ return 'before';
+ } else if(Math.abs(info.bottom-yPos) <= 10) {
+ $holder.css({top:info.bottom-10,height:'10px'});
+ return 'after';
+ }
+}
+
+});
diff --git a/modules/admin/tpl/menu_setup.html b/modules/admin/tpl/menu_setup.html
index 64c0bc3b5..69daced0a 100644
--- a/modules/admin/tpl/menu_setup.html
+++ b/modules/admin/tpl/menu_setup.html
@@ -1,5 +1,5 @@
-
+
{$XE_VALIDATOR_MESSAGE}
@@ -10,18 +10,18 @@
Admin Menu Setup
-
+