/*! * jQuery UI Sortable 1.7.2 => 1.8.22 */ (function( $, undefined ) { $.widget("ui.sortable.full", $.ui.sortable, { options: { nested:false, maxLevels: 100, maxItems : [] }, _rearrange: function(event, i, a, hardRefresh) { var haschildNode = this._hasChildNodes(i.item); // do this if is if(this.options.nested && this.error){ if(this._storedCursor) $('body').css("cursor", this._storedCursor); this.error = false; } if(!this.options.nested){ a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction == 'down' ? i.item[0] : i.item[0].nextSibling)); }else{ var level = this._getLevel(i.item); var childlevels = this._getChildLevels(this.helper); // aantal items op deze level if(this.options.maxLevels <= level+childlevels){ if(this.error != true){ this._storedCursor = $('body').css("cursor"); $('body').css("cursor", "not-allowed"); //Reset cursor this.error = true; } }else{ if(!$.ui.isOverAxis(this.positionAbs.left, i.left, i.width)){ if(this.options.maxItems.length <= level-1 || (i.item.closest(this.options.nested).children(this.options.items).not(".ui-sortable-helper,.ui-sortable-placeholder").length < this.options.maxItems[level-1])){ // als maxitems niet berijkt voor level a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction == 'down' ? i.item[0] : i.item[0].nextSibling)); }else{ this._storedCursor = $('body').css("cursor"); $('body').css("cursor", "not-allowed"); //Reset cursor this.error = true; } }else{ if(i.item.find(this.options.nested).siblings().length<=0){ var element = document.createElement(this.options.nested); i.item.append($(element)); } if(this.options.maxItems.length <= level || (i.item.children(this.options.nested).children(this.options.items).not(".ui-sortable-helper,.ui-sortable-placeholder").length < this.options.maxItems[level])){ //i.item.find(this.options.nested)[0].appendChild(this.placeholder[0],i.item.find(this.options.nested)[0].firstChild); i.item.find(this.options.nested)[0].insertBefore(this.placeholder[0],i.item.find(this.options.nested)[0].firstChild); }else{ this._storedCursor = $('body').css("cursor"); $('body').css("cursor", "not-allowed"); //Reset cursor this.error = true; } } } } // a ? 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 = this, counter = this.counter; window.setTimeout(function() { if(counter == self.counter) self.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove },0); }, // >>>>> _hasChildNodes:function(item){ if(this.options.nested){ if(item.find(this.options.nested) && item.find(this.options.nested).children(this.options.items).length>0){ return true; }else{ return false; } } }, _getChildLevels:function(item){ levels = item.find(this.options.items).filter(this.options.items+":first-child").length; return levels; }, _getLevel:function(item){ var level =1; if(this.options.nested){ var list = item.closest(this.options.nested); //.ui-sortable while(!list.is(".ui-sortable") && level < this.options.maxLevels){ level++; list = list.parent().closest(this.options.nested); } } return level; }, _getItemsOnLevel:function(item){ //console.log(item.closest(this.options.nested).html()) return item.closest(this.options.nested).children(this.options.items).not('.ui-sortable-placeholder').length; }, // <<<<<< _clear: function(event, noPropagation) { 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.parent().length) this.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 && !noPropagation) delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); }); if((this.fromOutside || this.domPosition.prev != this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent != this.currentItem.parent()[0]) && !noPropagation) delayedTriggers.push(function(event) { this._trigger("update", event, this._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(!noPropagation) delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); }); for (var i = this.containers.length - 1; i >= 0; i--){ if($.ui.contains(this.containers[i].element[0], this.currentItem[0]) && !noPropagation) { delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.containers[i])); delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.containers[i])); } }; }; //Post events to containers for (var i = this.containers.length - 1; i >= 0; i--){ if(!noPropagation) delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); }; }).call(this, this.containers[i])); if(this.containers[i].containerCache.over) { delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); }; }).call(this, this.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._storedOpacity) this.helper.css("opacity", this._storedOpacity); //Reset opacity if(this._storedZIndex) this.helper.css("zIndex", this._storedZIndex == 'auto' ? '' : this._storedZIndex); //Reset z-index this.dragging = false; if(this.cancelHelperRemoval) { if(!noPropagation) { this._trigger("beforeStop", event, this._uiHash()); for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events this._trigger("stop", event, this._uiHash()); } this.fromOutside = false; return false; } if(!noPropagation) this._trigger("beforeStop", event, this._uiHash()); //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it 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; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events this._trigger("stop", event, this._uiHash()); } // >>>>>>>>>>>> //b-hind clear empty nested elements if(this.options.nested){ this.element.find(this.options.nested+":empty").remove(); } // <<<<<<<<<<<< this.fromOutside = false; return true; } }); /* $.extend($.ui.sortable, { version: "1.0.0" }); */ })(jQuery);