CLICK HERE TO BUY IT TODAY! OR GET IT FREE VIA TRIALPAY  

PHP Demo Application - Source Code

/Framework/Model/Vendor/jquery-ui/development-bundle/ui/jquery.ui.sortable.js



/*
 * jQuery UI Sortable 1.8.4
 *
 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Sortables
 *
 * Depends:
 *    jquery.ui.core.js
 *    jquery.ui.mouse.js
 *    jquery.ui.widget.js
 */
(function( $, undefined ) {
	$.widget("ui.sortable", $.ui.mouse, {
		    widgetEventPrefix"sort",
		    options: {
			        appendTo"parent",
			        axisfalse,
			        connectWithfalse,
			        containmentfalse,
			        cursor'auto',
			        cursorAtfalse,
			        dropOnEmptytrue,
			        forcePlaceholderSizefalse,
			        forceHelperSizefalse,
			        gridfalse,
			        handlefalse,
			        helper"original",
			        items'> *',
			        opacityfalse,
			        placeholderfalse,
			        revertfalse,
			        scrolltrue,
			        scrollSensitivity20,
			        scrollSpeed20,
			        scope"default",
			        tolerance"intersect",
			        zIndex1000
			    },
		    _create: function() {
			        var this.options;
			        this.containerCache {};
			        this.element.addClass("ui-sortable");
			        //Get the items
			        this.refresh();
			        //Let's determine if the items are floating
			        this.floating this.items.length ? (/left|right/).test(this.items[0].item.css('float')) : false;
			        //Let's determine the parent's offset
			        this.offset this.element.offset();
			        //Initialize mouse events for interaction
			        this._mouseInit();
			    },
		    destroy: function() {
			        this.element
			            .removeClass("ui-sortable ui-sortable-disabled")
			            .removeData("sortable")
			            .unbind(".sortable");
			        this._mouseDestroy();
			        for ( var this.items.length 1;
			 >= 0;
			 i-- )
			            this.items[i].item.removeData("sortable-item");
			        return this;
			    },
		    _setOption: function(keyvalue){
			        if ( key === "disabled" ) {
				            this.optionskey ] = value;
				            this.widget()
				                [ value "addClass" "removeClass"]( "ui-sortable-disabled" );
				        } else {
				            // Don't call widget base _setOption for disable as it adds ui-state-disabled class
				            $.Widget.prototype._setOption.apply(thisarguments);
				        }
			    },
		    _mouseCapture: function(eventoverrideHandle) {
			        if (this.reverting) {
				            return false;
				        }
			        if(this.options.disabled || this.options.type == 'static') return false;
			        //We have to refresh the items data once first
			        this._refreshItems(event);
			        //Find out if the clicked node (or one of its parents) is a actual item in this.items
			        var currentItem nullself thisnodes = $(event.target).parents().each(function() {
				            if($.data(this'sortable-item') == self) {
					                currentItem = $(this);
					                return false;
					            }
				        });
			        if($.data(event.target'sortable-item') == selfcurrentItem = $(event.target);
			        if(!currentItem) return false;
			        if(this.options.handle && !overrideHandle) {
				            var validHandle false;
				            $(this.options.handlecurrentItem).find("*").andSelf().each(function() {
					if(this == event.targetvalidHandle true;
					});
				            if(!validHandle) return false;
				        }
			        this.currentItem currentItem;
			        this._removeCurrentsFromItems();
			        return true;
			    },
		    _mouseStart: function(eventoverrideHandlenoActivation) {
			        var this.optionsself this;
			        this.currentContainer this;
			        //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
			        this.refreshPositions();
			        //Create and append the visible helper
			        this.helper this._createHelper(event);
			        //Cache the helper size
			        this._cacheHelperProportions();
			        /*
			         * - Position generation -
			         * This block generates everything position related - it's the core of draggables.
			         */
			        //Cache the margins of the original element
			        this._cacheMargins();
			        //Get the next scrolling parent
			        this.scrollParent this.helper.scrollParent();
			        //The element's absolute position on the page minus margins
			        this.offset this.currentItem.offset();
			        this.offset = {
				            topthis.offset.top this.margins.top,
				            leftthis.offset.left this.margins.left
				        };
			        // Only after we got the offset, we can change the helper's position to absolute
			        // TODO: Still need to figure out a way to make relative sorting possible
			        this.helper.css("position""absolute");
			        this.cssPosition this.helper.css("position");
			        $.extend(this.offset, {
				            click: { //Where the click happened, relative to the element
					                leftevent.pageX this.offset.left,
					                topevent.pageY this.offset.top
					            },
				            parentthis._getParentOffset(),
				            relativethis._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
				        });
			        //Generate the original position
			        this.originalPosition this._generatePosition(event);
			        this.originalPageX event.pageX;
			        this.originalPageY event.pageY;
			        //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
			        (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
			        //Cache the former DOM position
			        this.domPosition = { prevthis.currentItem.prev()[0], parentthis.currentItem.parent()[0]
				};
			        //If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way
			        if(this.helper[0] != this.currentItem[0]) {
				            this.currentItem.hide();
				        }
			        //Create the placeholder
			        this._createPlaceholder();
			        //Set a containment if given in the options
			        if(o.containment)
			            this._setContainment();
			        if(o.cursor) {
				// cursor option
				            if ($('body').css("cursor")) this._storedCursor = $('body').css("cursor");
				            $('body').css("cursor"o.cursor);
				        }
			        if(o.opacity) {
				// opacity option
				            if (this.helper.css("opacity")) this._storedOpacity this.helper.css("opacity");
				            this.helper.css("opacity"o.opacity);
				        }
			        if(o.zIndex) {
				// zIndex option
				            if (this.helper.css("zIndex")) this._storedZIndex this.helper.css("zIndex");
				            this.helper.css("zIndex"o.zIndex);
				        }
			        //Prepare scrolling
			        if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML')
			            this.overflowOffset this.scrollParent.offset();
			        //Call callbacks
			        this._trigger("start"eventthis._uiHash());
			        //Recache the helper size
			        if(!this._preserveHelperProportions)
			            this._cacheHelperProportions();
			        //Post 'activate' events to possible containers
			        if(!noActivation) {
				             for (var this.containers.length 1;
				 >= 0;
				 i--) {
					this.containers[i]._trigger("activate"eventself._uiHash(this));
					}
				        }
			        //Prepare possible droppables
			        if($.ui.ddmanager)
			            $.ui.ddmanager.current this;
			        if ($.ui.ddmanager && !o.dropBehaviour)
			            $.ui.ddmanager.prepareOffsets(thisevent);
			        this.dragging true;
			        this.helper.addClass("ui-sortable-helper");
			        this._mouseDrag(event);
			 //Execute the drag once - this causes the helper not to be visible before getting its correct position
			        return true;
			    },
		    _mouseDrag: function(event) {
			        //Compute the helpers position
			        this.position this._generatePosition(event);
			        this.positionAbs this._convertPositionTo("absolute");
			        if (!this.lastPositionAbs) {
				            this.lastPositionAbs this.positionAbs;
				        }
			        //Do scrolling
			        if(this.options.scroll) {
				            var this.optionsscrolled false;
				            if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') {
					                if((this.overflowOffset.top this.scrollParent[0].offsetHeight) - event.pageY o.scrollSensitivity)
					                    this.scrollParent[0].scrollTop scrolled this.scrollParent[0].scrollTop o.scrollSpeed;
					                else if(event.pageY this.overflowOffset.top o.scrollSensitivity)
					                    this.scrollParent[0].scrollTop scrolled this.scrollParent[0].scrollTop o.scrollSpeed;
					                if((this.overflowOffset.left this.scrollParent[0].offsetWidth) - event.pageX o.scrollSensitivity)
					                    this.scrollParent[0].scrollLeft scrolled this.scrollParent[0].scrollLeft o.scrollSpeed;
					                else if(event.pageX this.overflowOffset.left o.scrollSensitivity)
					                    this.scrollParent[0].scrollLeft scrolled this.scrollParent[0].scrollLeft o.scrollSpeed;
					            } else {
					                if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
					                    scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
					                else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
					                    scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
					                if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
					                    scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
					                else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
					                    scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
					            }
				            if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
				                $.ui.ddmanager.prepareOffsets(thisevent);
				        }
			        //Regenerate the absolute position used for position checks
			        this.positionAbs this._convertPositionTo("absolute");
			        //Set the helper position
			        if(!this.options.axis || this.options.axis != "y"this.helper[0].style.left this.position.left+'px';
			        if(!this.options.axis || this.options.axis != "x"this.helper[0].style.top this.position.top+'px';
			        //Rearrange
			        for (var this.items.length 1;
			 >= 0;
			 i--) {
				            //Cache variables and intersection, continue if no intersection
				            var item this.items[i], itemElement item.item[0], intersection this._intersectsWithPointer(item);
				            if (!intersection) continue;
				            if(itemElement != this.currentItem[0//cannot intersect with itself
				                &&    this.placeholder[intersection == "next" "prev"]()[0] != itemElement //no useless actions that have been done before
				                &&    !$.ui.contains(this.placeholder[0], itemElement//no action if the item moved is the parent of the item checked
				                && (this.options.type == 'semi-dynamic' ? !$.ui.contains(this.element[0], itemElement) : true)
				                //&& itemElement.parentNode == this.placeholder[0].parentNode // only rearrange items within the same container
				            ) {
					                this.direction intersection == "down" "up";
					                if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) {
						                    this._rearrange(eventitem);
						                } else {
						                    break;
						                }
					                this._trigger("change"eventthis._uiHash());
					                break;
					            }
				        }
			        //Post events to containers
			        this._contactContainers(event);
			        //Interconnect with droppables
			        if($.ui.ddmanager) $.ui.ddmanager.drag(thisevent);
			        //Call callbacks
			        this._trigger('sort'eventthis._uiHash());
			        this.lastPositionAbs this.positionAbs;
			        return false;
			    },
		    _mouseStop: function(eventnoPropagation) {
			        if(!event) return;
			        //If we are using droppables, inform the manager about the drop
			        if ($.ui.ddmanager && !this.options.dropBehaviour)
			            $.ui.ddmanager.drop(thisevent);
			        if(this.options.revert) {
				            var self this;
				            var cur self.placeholder.offset();
				            self.reverting true;
				            $(this.helper).animate({
					                leftcur.left this.offset.parent.left self.margins.left + (this.offsetParent[0] == document.body this.offsetParent[0].scrollLeft),
					                topcur.top this.offset.parent.top self.margins.top + (this.offsetParent[0] == document.body this.offsetParent[0].scrollTop)
					            }, parseInt(this.options.revert10) || 500, function() {
					                self._clear(event);
					            });
				        } else {
				            this._clear(eventnoPropagation);
				        }
			        return false;
			    },
		    cancel: function() {
			        var self this;
			        if(this.dragging) {
				            this._mouseUp();
				            if(this.options.helper == "original")
				                this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
				            else
				                this.currentItem.show();
				            //Post deactivating events to containers
				            for (var this.containers.length 1;
				 >= 0;
				 i--){
					                this.containers[i]._trigger("deactivate"nullself._uiHash(this));
					                if(this.containers[i].containerCache.over) {
						                    this.containers[i]._trigger("out"nullself._uiHash(this));
						                    this.containers[i].containerCache.over 0;
						                }
					            }
				        }
			        //$(this.placeholder[0]).remove();
			 would have been the jQuery way unfortunatelyit unbinds ALL events from the original node!
			        if(this.placeholder[0].parentNodethis.placeholder[0].parentNode.removeChild(this.placeholder[0]);
			        if(this.options.helper != "original" && this.helper && this.helper[0].parentNodethis.helper.remove();
			        $.extend(this, {
				            helpernull,
				            draggingfalse,
				            revertingfalse,
				            _noFinalSortnull
				        });
			        if(this.domPosition.prev) {
				            $(this.domPosition.prev).after(this.currentItem);
				        } else {
				            $(this.domPosition.parent).prepend(this.currentItem);
				        }
			        return this;
			    },
		    serialize: function(o) {
			        var items this._getItemsAsjQuery(&& o.connected);
			        var str [];
			 || {};
			        $(items).each(function() {
				            var res = ($(o.item || this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
				            if(resstr.push((o.key || res[1]+'[]')+'='+(o.key && o.expression res[1] : res[2]));
				        });
			        if(!str.length && o.key) {
				            str.push(o.key '=');
				        }
			        return str.join('&');
			    },
		    toArray: function(o) {
			        var items this._getItemsAsjQuery(&& o.connected);
			        var ret [];
			 || {};
			        items.each(function() {
				ret.push($(o.item || this).attr(o.attribute || 'id') || '');
				});
			        return ret;
			    },
		    /* Be careful with the following core functions */
		    _intersectsWith: function(item) {
			        var x1 this.positionAbs.left,
			            x2 x1 this.helperProportions.width,
			            y1 this.positionAbs.top,
			            y2 y1 this.helperProportions.height;
			        var item.left,
			            item.width,
			            item.top,
			            item.height;
			        var dyClick this.offset.click.top,
			            dxClick this.offset.click.left;
			        var isOverElement = (y1 dyClick) > && (y1 dyClick) < && (x1 dxClick) > && (x1 dxClick) < r;
			        if(       this.options.tolerance == "pointer"
			            || this.options.forcePointerForContainers
			            || (this.options.tolerance != "pointer" && this.helperProportions[this.floating 'width' 'height'] > item[this.floating 'width' 'height'])
			        ) {
				            return isOverElement;
				        } else {
				            return (x1 + (this.helperProportions.width 2// Right Half
				                && x2 - (this.helperProportions.width 2) < // Left Half
				                && y1 + (this.helperProportions.height 2// Bottom Half
				                && y2 - (this.helperProportions.height 2) < );
				 // Top Half
				        }
			    },
		    _intersectsWithPointer: function(item) {
			        var isOverElementHeight = $.ui.isOverAxis(this.positionAbs.top this.offset.click.topitem.topitem.height),
			            isOverElementWidth = $.ui.isOverAxis(this.positionAbs.left this.offset.click.leftitem.leftitem.width),
			            isOverElement isOverElementHeight && isOverElementWidth,
			            verticalDirection this._getDragVerticalDirection(),
			            horizontalDirection this._getDragHorizontalDirection();
			        if (!isOverElement)
			            return false;
			        return this.floating ?
			            ( ((horizontalDirection && horizontalDirection == "right") || verticalDirection == "down") ? )
			            : ( verticalDirection && (verticalDirection == "down" 1) );
			    },
		    _intersectsWithSides: function(item) {
			        var isOverBottomHalf = $.ui.isOverAxis(this.positionAbs.top this.offset.click.topitem.top + (item.height/2), item.height),
			            isOverRightHalf = $.ui.isOverAxis(this.positionAbs.left this.offset.click.leftitem.left + (item.width/2), item.width),
			            verticalDirection this._getDragVerticalDirection(),
			            horizontalDirection this._getDragHorizontalDirection();
			        if (this.floating && horizontalDirection) {
				            return ((horizontalDirection == "right" && isOverRightHalf) || (horizontalDirection == "left" && !isOverRightHalf));
				        } else {
				            return verticalDirection && ((verticalDirection == "down" && isOverBottomHalf) || (verticalDirection == "up" && !isOverBottomHalf));
				        }
			    },
		    _getDragVerticalDirection: function() {
			        var delta this.positionAbs.top this.lastPositionAbs.top;
			        return delta != && (delta "down" "up");
			    },
		    _getDragHorizontalDirection: function() {
			        var delta this.positionAbs.left this.lastPositionAbs.left;
			        return delta != && (delta "right" "left");
			    },
		    refresh: function(event) {
			        this._refreshItems(event);
			        this.refreshPositions();
			        return this;
			    },
		    _connectWith: function() {
			        var options this.options;
			        return options.connectWith.constructor == String
			            ? [options.connectWith]
			            : options.connectWith;
			    },
		    _getItemsAsjQuery: function(connected) {
			        var self this;
			        var items [];
			        var queries [];
			        var connectWith this._connectWith();
			        if(connectWith && connected) {
				            for (var connectWith.length 1;
				 >= 0;
				 i--){
					                var cur = $(connectWith[i]);
					                for (var cur.length 1;
					 >= 0;
					 j--){
						                    var inst = $.data(cur[j], 'sortable');
						                    if(inst && inst != this && !inst.options.disabled) {
							                        queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.itemsinst.element).not(".ui-sortable-helper").not('.ui-sortable-placeholder'), inst]);
							                    }
						                };
					            };
				        }
			        queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.elementnull, { optionsthis.optionsitemthis.currentItem
				}) : $(this.options.itemsthis.element).not(".ui-sortable-helper").not('.ui-sortable-placeholder'), this]);
			        for (var queries.length 1;
			 >= 0;
			 i--){
				            queries[i][0].each(function() {
					                items.push(this);
					            });
				        };
			        return $(items);
			    },
		    _removeCurrentsFromItems: function() {
			        var list = this.currentItem.find(":data(sortable-item)");
			        for (var i=0;
			 this.items.length;
			 i++) {
				            for (var j=0;
				 < list.length;
				 j++) {
					                if(list[j] == this.items[i].item[0])
					                    this.items.splice(i,1);
					            };
				        };
			    },
		    _refreshItems: function(event) {
			        this.items [];
			        this.containers = [this];
			        var items this.items;
			        var self this;
			        var queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { itemthis.currentItem
				}) : $(this.options.itemsthis.element), this]];
			        var connectWith this._connectWith();
			        if(connectWith) {
				            for (var connectWith.length 1;
				 >= 0;
				 i--){
					                var cur = $(connectWith[i]);
					                for (var cur.length 1;
					 >= 0;
					 j--){
						                    var inst = $.data(cur[j], 'sortable');
						                    if(inst && inst != this && !inst.options.disabled) {
							                        queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { itemthis.currentItem
								}) : $(inst.options.itemsinst.element), inst]);
							                        this.containers.push(inst);
							                    }
						                };
					            };
				        }
			        for (var queries.length 1;
			 >= 0;
			 i--) {
				            var targetData queries[i][1];
				            var _queries queries[i][0];
				            for (var j=0queriesLength _queries.length;
				 queriesLength;
				 j++) {
					                var item = $(_queries[j]);
					                item.data('sortable-item'targetData);
					 // Data for target checking (mouse manager)
					                items.push({
						                    itemitem,
						                    instancetargetData,
						                    width0height0,
						                    left0top0
						                });
					            };
				        };
			    },
		    refreshPositions: function(fast) {
			        //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
			        if(this.offsetParent && this.helper) {
				            this.offset.parent this._getParentOffset();
				        }
			        for (var this.items.length 1;
			 >= 0;
			 i--){
				            var item this.items[i];
				            var this.options.toleranceElement ? $(this.options.toleranceElementitem.item) : item.item;
				            if (!fast) {
					                item.width t.outerWidth();
					                item.height t.outerHeight();
					            }
				            var t.offset();
				            item.left p.left;
				            item.top p.top;
				        };
			        if(this.options.custom && this.options.custom.refreshContainers) {
				            this.options.custom.refreshContainers.call(this);
				        } else {
				            for (var this.containers.length 1;
				 >= 0;
				 i--){
					                var this.containers[i].element.offset();
					                this.containers[i].containerCache.left p.left;
					                this.containers[i].containerCache.top p.top;
					                this.containers[i].containerCache.width    this.containers[i].element.outerWidth();
					                this.containers[i].containerCache.height this.containers[i].element.outerHeight();
					            };
				        }
			        return this;
			    },
		    _createPlaceholder: function(that) {
			        var self that || thisself.options;
			        if(!o.placeholder || o.placeholder.constructor == String) {
				            var className o.placeholder;
				            o.placeholder = {
					                element: function() {
						                    var el = $(document.createElement(self.currentItem[0].nodeName))
						                        .addClass(className || self.currentItem[0].className+" ui-sortable-placeholder")
						                        .removeClass("ui-sortable-helper")[0];
						                    if(!className)
						                        el.style.visibility "hidden";
						                    return el;
						                },
					                update: function(containerp) {
						                    // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
						                    // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
						                    if(className && !o.forcePlaceholderSize) return;
						                    //If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item
						                    if(!p.height()) {
							p.height(self.currentItem.innerHeight() - parseInt(self.currentItem.css('paddingTop')||010) - parseInt(self.currentItem.css('paddingBottom')||010));
							};
						                    if(!p.width()) {
							p.width(self.currentItem.innerWidth() - parseInt(self.currentItem.css('paddingLeft')||010) - parseInt(self.currentItem.css('paddingRight')||010));
							};
						                }
					            };
				        }
			        //Create the placeholder
			        self.placeholder = $(o.placeholder.element.call(self.elementself.currentItem));
			        //Append it after the actual current item
			        self.currentItem.after(self.placeholder);
			        //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
			        o.placeholder.update(selfself.placeholder);
			    },
		    _contactContainers: function(event) {
			        // get innermost container that intersects with item 
			        var innermostContainer nullinnermostIndex null;
			        for (var this.containers.length 1;
			 >= 0;
			 i--){
				            // never consider a container that's located within the item itself 
				            if($.ui.contains(this.currentItem[0], this.containers[i].element[0]))
				                continue;
				            if(this._intersectsWith(this.containers[i].containerCache)) {
					                // if we've already found a container and it's more "inner" than this, then continue 
					                if(innermostContainer && $.ui.contains(this.containers[i].element[0], innermostContainer.element[0]))
					                    continue;
					                innermostContainer this.containers[i];
					                innermostIndex i;
					            } else {
					                // container doesn't intersect. trigger "out" event if necessary 
					                if(this.containers[i].containerCache.over) {
						                    this.containers[i]._trigger("out"eventthis._uiHash(this));
						                    this.containers[i].containerCache.over 0;
						                }
					            }
				        }
			        // if no intersecting containers found, return 
			        if(!innermostContainer) return;
			        // move the item into the container if it's not there already
			        if(this.containers.length === 1) {
				            this.containers[innermostIndex]._trigger("over"eventthis._uiHash(this));
				            this.containers[innermostIndex].containerCache.over 1;
				        } else if(this.currentContainer != this.containers[innermostIndex]) {
				            //When entering a new container, we will find the item with the least distance and append our item near it 
				            var dist 10000;
				 var itemWithLeastDistance null;
				 var base this.positionAbs[this.containers[innermostIndex].floating 'left' 'top'];
				            for (var this.items.length 1;
				 >= 0;
				 j--) {
					                if(!$.ui.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) continue;
					                var cur this.items[j][this.containers[innermostIndex].floating 'left' 'top'];
					                if(Math.abs(cur base) < dist) {
						                    dist Math.abs(cur base);
						 itemWithLeastDistance this.items[j];
						                } 
					            } 
				            if(!itemWithLeastDistance && !this.options.dropOnEmpty//Check if dropOnEmpty is enabled 
				                return;
				            this.currentContainer this.containers[innermostIndex];
				            itemWithLeastDistance this._rearrange(eventitemWithLeastDistancenulltrue) : this._rearrange(eventnullthis.containers[innermostIndex].elementtrue);
				            this._trigger("change"eventthis._uiHash());
				            this.containers[innermostIndex]._trigger("change"eventthis._uiHash(this));
				            //Update the placeholder 
				            this.options.placeholder.update(this.currentContainerthis.placeholder);
				            this.containers[innermostIndex]._trigger("over"eventthis._uiHash(this));
				            this.containers[innermostIndex].containerCache.over 1;
				        } 
			    },
		    _createHelper: function(event) {
			        var this.options;
			        var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [eventthis.currentItem])) : (o.helper == 'clone' this.currentItem.clone() : this.currentItem);
			        if(!helper.parents('body').length//Add the helper to the DOM if that didn't happen already
			            $(o.appendTo != 'parent' o.appendTo this.currentItem[0].parentNode)[0].appendChild(helper[0]);
			        if(helper[0] == this.currentItem[0])
			            this._storedCSS = { widththis.currentItem[0].style.widthheightthis.currentItem[0].style.heightpositionthis.currentItem.css("position"), topthis.currentItem.css("top"), leftthis.currentItem.css("left")
				};
			        if(helper[0].style.width == '' || o.forceHelperSizehelper.width(this.currentItem.width());
			        if(helper[0].style.height == '' || o.forceHelperSizehelper.height(this.currentItem.height());
			        return helper;
			    },
		    _adjustOffsetFromHelper: function(obj) {
			        if (typeof obj == 'string') {
				            obj obj.split(' ');
				        }
			        if ($.isArray(obj)) {
				            obj = {left: +obj[0], top: +obj[1] || 0};
				        }
			        if ('left' in obj) {
				            this.offset.click.left obj.left this.margins.left;
				        }
			        if ('right' in obj) {
				            this.offset.click.left this.helperProportions.width obj.right this.margins.left;
				        }
			        if ('top' in obj) {
				            this.offset.click.top obj.top this.margins.top;
				        }
			        if ('bottom' in obj) {
				            this.offset.click.top this.helperProportions.height obj.bottom this.margins.top;
				        }
			    },
		    _getParentOffset: function() {
			        //Get the offsetParent and cache its position
			        this.offsetParent this.helper.offsetParent();
			        var po this.offsetParent.offset();
			        // This is a special case where we need to modify a offset calculated on start, since the following happened:
			        // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
			        // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
			        //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
			        if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) {
				            po.left += this.scrollParent.scrollLeft();
				            po.top += this.scrollParent.scrollTop();
				        }
			        if((this.offsetParent[0] == document.body//This needs to be actually done for all browsers, since pageX/pageY includes this information
			        || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix
			            po = { top0left0
				};
			        return {
				            toppo.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
				            leftpo.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
				        };
			    },
		    _getRelativeOffset: function() {
			        if(this.cssPosition == "relative") {
				            var this.currentItem.position();
				            return {
					                topp.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
					                leftp.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
					            };
				        } else {
				            return { top0left0
					};
				        }
			    },
		    _cacheMargins: function() {
			        this.margins = {
				            left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
				            top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
				        };
			    },
		    _cacheHelperProportions: function() {
			        this.helperProportions = {
				            widththis.helper.outerWidth(),
				            heightthis.helper.outerHeight()
				        };
			    },
		    _setContainment: function() {
			        var this.options;
			        if(o.containment == 'parent'o.containment this.helper[0].parentNode;
			        if(o.containment == 'document' || o.containment == 'window'this.containment = [
			            this.offset.relative.left this.offset.parent.left,
			            this.offset.relative.top this.offset.parent.top,
			            $(o.containment == 'document' document window).width() - this.helperProportions.width this.margins.left,
			            ($(o.containment == 'document' document window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height this.margins.top
			        ];
			        if(!(/^(document|window|parent)$/).test(o.containment)) {
				            var ce = $(o.containment)[0];
				            var co = $(o.containment).offset();
				            var over = ($(ce).css("overflow") != 'hidden');
				            this.containment = [
				                co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
				                co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
				                co.left+(over Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width this.margins.left,
				                co.top+(over Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height this.margins.top
				            ];
				        }
			    },
		    _convertPositionTo: function(dpos) {
			        if(!pospos this.position;
			        var mod == "absolute" : -1;
			        var this.optionsscroll this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent this.scrollParentscrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
			        return {
				            top: (
				                pos.top                                                                    // The absolute mouse position
				                this.offset.relative.top mod                                        // Only for relative positioned nodes: Relative offset from element to offset parent
				                this.offset.parent.top mod                                            // The offsetParent's offset without borders (offset + border)
				                - ($.browser.safari && this.cssPosition == 'fixed' : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode scroll.scrollTop() ) ) * mod)
				            ),
				            left: (
				                pos.left                                                                // The absolute mouse position
				                this.offset.relative.left mod                                        // Only for relative positioned nodes: Relative offset from element to offset parent
				                this.offset.parent.left mod                                            // The offsetParent's offset without borders (offset + border)
				                - ($.browser.safari && this.cssPosition == 'fixed' : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode scroll.scrollLeft() ) * mod)
				            )
				        };
			    },
		    _generatePosition: function(event) {
			        var this.optionsscroll this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent this.scrollParentscrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
			        // This is another very weird special case that only happens for relative elements:
			        // 1. If the css position is relative
			        // 2. and the scroll parent is the document or similar to the offset parent
			        // we have to refresh the relative offset during the scroll so there are no jumps
			        if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) {
				            this.offset.relative this._getRelativeOffset();
				        }
			        var pageX event.pageX;
			        var pageY event.pageY;
			        /*
			         * - Position constraining -
			         * Constrain the position to a mix of grid, containment.
			         */
			        if(this.originalPosition) {
				//If we are not dragging yet, we won't check for options
				            if(this.containment) {
					                if(event.pageX this.offset.click.left this.containment[0]) pageX this.containment[0] + this.offset.click.left;
					                if(event.pageY this.offset.click.top this.containment[1]) pageY this.containment[1] + this.offset.click.top;
					                if(event.pageX this.offset.click.left this.containment[2]) pageX this.containment[2] + this.offset.click.left;
					                if(event.pageY this.offset.click.top this.containment[3]) pageY this.containment[3] + this.offset.click.top;
					            }
				            if(o.grid) {
					                var top this.originalPageY Math.round((pageY this.originalPageY) / o.grid[1]) * o.grid[1];
					                pageY this.containment ? (!(top this.offset.click.top this.containment[1] || top this.offset.click.top this.containment[3]) ? top : (!(top this.offset.click.top this.containment[1]) ? top o.grid[1] : top o.grid[1])) : top;
					                var left this.originalPageX Math.round((pageX this.originalPageX) / o.grid[0]) * o.grid[0];
					                pageX this.containment ? (!(left this.offset.click.left this.containment[0] || left this.offset.click.left this.containment[2]) ? left : (!(left this.offset.click.left this.containment[0]) ? left o.grid[0] : left o.grid[0])) : left;
					            }
				        }
			        return {
				            top: (
				                pageY                                                                // The absolute mouse position
				                this.offset.click.top                                                    // Click offset (relative to the element)
				                this.offset.relative.top                                                // Only for relative positioned nodes: Relative offset from element to offset parent
				                this.offset.parent.top                                                // The offsetParent's offset without borders (offset + border)
				                + ($.browser.safari && this.cssPosition == 'fixed' : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode scroll.scrollTop() ) ))
				            ),
				            left: (
				                pageX                                                                // The absolute mouse position
				                this.offset.click.left                                                // Click offset (relative to the element)
				                this.offset.relative.left                                                // Only for relative positioned nodes: Relative offset from element to offset parent
				                this.offset.parent.left                                                // The offsetParent's offset without borders (offset + border)
				                + ($.browser.safari && this.cssPosition == 'fixed' : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode scroll.scrollLeft() ))
				            )
				        };
			    },
		    _rearrange: function(eventiahardRefresh) {
			        a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction == 'down' i.item[0] : i.item[0].nextSibling));
			        //Various things done here to improve the performance:
			        // 1. we create a setTimeout, that calls refreshPositions
			        // 2. on the instance, we have a counter variable, that get's higher after every append
			        // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
			        // 4. this lets only the last addition to the timeout stack through
			        this.counter this.counter ? ++this.counter 1;
			        var self thiscounter this.counter;
			        window.setTimeout(function() {
				            if(counter == self.counterself.refreshPositions(!hardRefresh);
				 //Precompute after each DOM insertion, NOT on mousemove
				        },0);
			    },
		    _clear: function(eventnoPropagation) {
			        this.reverting false;
			        // We delay all events that have to be triggered to after the point where the placeholder has been removed and
			        // everything else normalized again
			        var delayedTriggers []self this;
			        // We first have to update the dom position of the actual currentItem
			        // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
			        if(!this._noFinalSort && this.currentItem[0].parentNodethis.placeholder.before(this.currentItem);
			        this._noFinalSort null;
			        if(this.helper[0] == this.currentItem[0]) {
				            for(var i in this._storedCSS) {
					                if(this._storedCSS[i] == 'auto' || this._storedCSS[i] == 'static'this._storedCSS[i] = '';
					            }
				            this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
				        } else {
				            this.currentItem.show();
				        }
			        if(this.fromOutside && !noPropagationdelayedTriggers.push(function(event) {
				this._trigger("receive"eventthis._uiHash(this.fromOutside));
				});
			        if((this.fromOutside || this.domPosition.prev != this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent != this.currentItem.parent()[0]) && !noPropagationdelayedTriggers.push(function(event) {
				this._trigger("update"eventthis._uiHash());
				});
			 //Trigger update callback if the DOM position has changed
			        if(!$.ui.contains(this.element[0], this.currentItem[0])) {
				//Node was moved out of the current element
				            if(!noPropagationdelayedTriggers.push(function(event) {
					this._trigger("remove"eventthis._uiHash());
					});
				            for (var this.containers.length 1;
				 >= 0;
				 i--){
					                if($.ui.contains(this.containers[i].element[0], this.currentItem[0]) && !noPropagation) {
						                    delayedTriggers.push((function(c) {
							return function(event) {
								c._trigger("receive"eventthis._uiHash(this));
								};
							}).call(thisthis.containers[i]));
						                    delayedTriggers.push((function(c) {
							return function(event) {
								c._trigger("update"eventthis._uiHash(this));
								};
							}).call(thisthis.containers[i]));
						                }
					            };
				        };
			        //Post events to containers
			        for (var this.containers.length 1;
			 >= 0;
			 i--){
				            if(!noPropagationdelayedTriggers.push((function(c) {
					return function(event) {
						c._trigger("deactivate"eventthis._uiHash(this));
						};
					}).call(thisthis.containers[i]));
				            if(this.containers[i].containerCache.over) {
					                delayedTriggers.push((function(c) {
						return function(event) {
							c._trigger("out"eventthis._uiHash(this));
							};
						}).call(thisthis.containers[i]));
					                this.containers[i].containerCache.over 0;
					            }
				        }
			        //Do what was originally in plugins
			        if(this._storedCursor) $('body').css("cursor"this._storedCursor);
			 //Reset cursor
			        if(this._storedOpacitythis.helper.css("opacity"this._storedOpacity);
			 //Reset opacity
			        if(this._storedZIndexthis.helper.css("zIndex"this._storedZIndex == 'auto' '' this._storedZIndex);
			 //Reset z-index
			        this.dragging false;
			        if(this.cancelHelperRemoval) {
				            if(!noPropagation) {
					                this._trigger("beforeStop"eventthis._uiHash());
					                for (var i=0;
					 delayedTriggers.length;
					 i++) {
						delayedTriggers[i].call(thisevent);
						};
					 //Trigger all delayed events
					                this._trigger("stop"eventthis._uiHash());
					            }
				            return false;
				        }
			        if(!noPropagationthis._trigger("beforeStop"eventthis._uiHash());
			        //$(this.placeholder[0]).remove();
			 would have been the jQuery way unfortunatelyit unbinds ALL events from the original node!
			        this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
			        if(this.helper[0] != this.currentItem[0]) this.helper.remove();
			 this.helper null;
			        if(!noPropagation) {
				            for (var i=0;
				 delayedTriggers.length;
				 i++) {
					delayedTriggers[i].call(thisevent);
					};
				 //Trigger all delayed events
				            this._trigger("stop"eventthis._uiHash());
				        }
			        this.fromOutside false;
			        return true;
			    },
		    _trigger: function() {
			        if ($.Widget.prototype._trigger.apply(thisarguments) === false) {
				            this.cancel();
				        }
			    },
		    _uiHash: function(inst) {
			        var self inst || this;
			        return {
				            helperself.helper,
				            placeholderself.placeholder || $([]),
				            positionself.position,
				            originalPositionself.originalPosition,
				            offsetself.positionAbs,
				            itemself.currentItem,
				            senderinst inst.element null
				        };
			    }
		});
	$.extend($.ui.sortable, {
		    version"1.8.4"
		});
	})(jQuery);





PHP Demo Source Code Index