![JAR search and dependency download from the Maven repository](/logo.png)
vendor.angular.angular-dragdrop.js Maven / Gradle / Ivy
The newest version!
/**
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
/**
* Implementing Drag and Drop functionality in AngularJS is easier than ever.
* Demo: http://codef0rmer.github.com/angular-dragdrop/
*
* @version 1.0.4
*
* (c) 2013 Amit Gharat a.k.a codef0rmer - amitgharat.wordpress.com
*/
/**
* This has been modified from the default angular-draganddrop to provide the original
* model and some other stuff as the 'data' arguement to callEventCallback
*/
(function (window, angular, undefined) {
'use strict';
var jqyoui = angular.module('ngDragDrop', []).service('ngDragDropService', ['$timeout', '$parse', function($timeout, $parse) {
this.callEventCallback = function (scope, callbackName, event, ui, data) {
if (!callbackName) {
return;
}
var args = [event, ui, data];
var match = callbackName.match(/^(.+)\((.+)\)$/);
if (match !== null) {
callbackName = match[1];
var values = eval('[' + match[0].replace(/^(.+)\(/, '').replace(/\)/, '') + ']');
args.push.apply(args, values);
}
if(scope[callbackName]) {
scope[callbackName].apply(scope, args);
}
};
this.invokeDrop = function ($draggable, $droppable, event, ui) {
var dragModel = '',
dropModel = '',
dragSettings = {},
dropSettings = {},
jqyoui_pos = null,
dragItem = {},
dropItem = {},
dragModelValue,
dropModelValue,
$droppableDraggable = null,
droppableScope = $droppable.scope(),
draggableScope = $draggable.scope(),
data = {};
dragModel = $draggable.ngattr('ng-model');
dropModel = $droppable.ngattr('ng-model');
dragModelValue = draggableScope.$eval(dragModel);
dropModelValue = droppableScope.$eval(dropModel);
$droppableDraggable = $droppable.find('[jqyoui-draggable]:last');
dropSettings = droppableScope.$eval($droppable.attr('jqyoui-droppable')) || [];
dragSettings = draggableScope.$eval($draggable.attr('jqyoui-draggable')) || [];
// Helps pick up the right item
dragSettings.index = this.fixIndex(draggableScope, dragSettings, dragModelValue);
dropSettings.index = this.fixIndex(droppableScope, dropSettings, dropModelValue);
jqyoui_pos = angular.isArray(dragModelValue) ? dragSettings.index : null;
dragItem = angular.isArray(dragModelValue) ? dragModelValue[jqyoui_pos] : dragModelValue;
if (angular.isArray(dropModelValue) && dropSettings && dropSettings.index !== undefined) {
dropItem = dropModelValue[dropSettings.index];
} else if (!angular.isArray(dropModelValue)) {
dropItem = dropModelValue;
} else {
dropItem = {};
}
data = {
dragModel: dragModel,
dropModel: dropModel,
dragSettings: dragSettings,
dropSettings: dropSettings,
jqyoui_pos: jqyoui_pos,
dragItem: dragItem,
dropItem: dropItem,
dragModelValue: dragModelValue,
dropModelValue: dropModelValue,
droppableScope: $droppable.scope(),
draggableScope: $draggable.scope()
};
if (dragSettings.animate === true) {
this.move($draggable, $droppableDraggable.length > 0 ? $droppableDraggable : $droppable, null, 'fast', dropSettings, null);
this.move($droppableDraggable.length > 0 && !dropSettings.multiple ? $droppableDraggable : [], $draggable.parent('[jqyoui-droppable]'), jqyoui.startXY, 'fast', dropSettings, function() {
$timeout(function() {
// Do not move this into move() to avoid flickering issue
$draggable.css({'position': 'relative', 'left': '', 'top': ''});
$droppableDraggable.css({'position': 'relative', 'left': '', 'top': ''});
if(dragSettings.mutate !== false) {
this.mutateDraggable(draggableScope, dropSettings, dragSettings, dragModel, dropModel, dropItem, $draggable);
}
if(dropSettings.mutate !== false) {
this.mutateDroppable(droppableScope, dropSettings, dragSettings, dropModel, dragItem, jqyoui_pos);
}
this.callEventCallback(droppableScope, dropSettings.onDrop, event, ui, data);
}.bind(this));
}.bind(this));
} else {
$timeout(function() {
if(dragSettings.mutate !== false) {
this.mutateDraggable(draggableScope, dropSettings, dragSettings, dragModel, dropModel, dropItem, $draggable);
}
if(dropSettings.mutate !== false) {
this.mutateDroppable(droppableScope, dropSettings, dragSettings, dropModel, dragItem, jqyoui_pos);
}
this.callEventCallback(droppableScope, dropSettings.onDrop, event, ui, data);
}.bind(this));
}
};
this.move = function($fromEl, $toEl, toPos, duration, dropSettings, callback) {
if ($fromEl.length === 0) {
if (callback) {
window.setTimeout(function() {
callback();
}, 300);
}
return false;
}
var zIndex = 9999,
fromPos = $fromEl.offset(),
wasVisible = $toEl && $toEl.is(':visible');
if (toPos === null && $toEl.length > 0) {
if ($toEl.attr('jqyoui-draggable') !== undefined && $toEl.ngattr('ng-model') !== undefined && $toEl.is(':visible') && dropSettings && dropSettings.multiple) {
toPos = $toEl.offset();
if (dropSettings.stack === false) {
toPos.left+= $toEl.outerWidth(true);
} else {
toPos.top+= $toEl.outerHeight(true);
}
} else {
toPos = $toEl.css({'visibility': 'hidden', 'display': 'block'}).offset();
$toEl.css({'visibility': '','display': wasVisible ? '' : 'none'});
}
}
$fromEl.css({'position': 'absolute', 'z-index': zIndex})
.css(fromPos)
.animate(toPos, duration, function() {
if (callback) callback();
});
};
this.mutateDroppable = function(scope, dropSettings, dragSettings, dropModel, dragItem, jqyoui_pos) {
var dropModelValue = scope.$eval(dropModel);
scope.__dragItem = dragItem;
if (angular.isArray(dropModelValue)) {
if (dropSettings && dropSettings.index >= 0) {
dropModelValue[dropSettings.index] = dragItem;
} else {
dropModelValue.push(dragItem);
}
if (dragSettings && dragSettings.placeholder === true) {
dropModelValue[dropModelValue.length - 1]['jqyoui_pos'] = jqyoui_pos;
}
} else {
$parse(dropModel + ' = __dragItem')(scope);
if (dragSettings && dragSettings.placeholder === true) {
dropModelValue['jqyoui_pos'] = jqyoui_pos;
}
}
};
this.mutateDraggable = function(scope, dropSettings, dragSettings, dragModel, dropModel, dropItem, $draggable) {
var isEmpty = angular.equals(angular.copy(dropItem), {}),
dragModelValue = scope.$eval(dragModel);
scope.__dropItem = dropItem;
if (dragSettings && dragSettings.placeholder) {
if (dragSettings.placeholder != 'keep'){
if (angular.isArray(dragModelValue) && dragSettings.index !== undefined) {
dragModelValue[dragSettings.index] = dropItem;
} else {
$parse(dragModel + ' = __dropItem')(scope);
}
}
} else {
if (angular.isArray(dragModelValue)) {
if (isEmpty) {
if (dragSettings && ( dragSettings.placeholder !== true && dragSettings.placeholder !== 'keep' )) {
dragModelValue.splice(dragSettings.index, 1);
}
} else {
dragModelValue[dragSettings.index] = dropItem;
}
} else {
// Fix: LIST(object) to LIST(array) - model does not get updated using just scope[dragModel] = {...}
// P.S.: Could not figure out why it happened
$parse(dragModel + ' = __dropItem')(scope);
if (scope.$parent) {
$parse(dragModel + ' = __dropItem')(scope.$parent);
}
}
}
$draggable.css({'z-index': '', 'left': '', 'top': ''});
};
this.fixIndex = function(scope, settings, modelValue) {
if (settings.applyFilter && angular.isArray(modelValue) && modelValue.length > 0) {
var dragModelValueFiltered = scope[settings.applyFilter](),
lookup = dragModelValueFiltered[settings.index],
actualIndex = undefined;
modelValue.forEach(function(item, i) {
if (angular.equals(item, lookup)) {
actualIndex = i;
}
});
return actualIndex;
}
return settings.index;
};
}]).directive('jqyouiDraggable', ['ngDragDropService', function(ngDragDropService) {
return {
require: '?jqyouiDroppable',
restrict: 'A',
link: function(scope, element, attrs) {
var dragSettings, zIndex;
var updateDraggable = function(newValue, oldValue) {
if (newValue) {
dragSettings = scope.$eval(element.attr('jqyoui-draggable')) || [];
element
.draggable({disabled: false})
.draggable(scope.$eval(attrs.jqyouiOptions) || {})
.draggable({
start: function(event, ui) {
zIndex = angular.element(this).css('z-index');
angular.element(this).css('z-index', 99999);
jqyoui.startXY = angular.element(this).offset();
ngDragDropService.callEventCallback(scope, dragSettings.onStart, event, ui);
},
stop: function(event, ui) {
angular.element(this).css('z-index', zIndex);
ngDragDropService.callEventCallback(scope, dragSettings.onStop, event, ui);
},
drag: function(event, ui) {
ngDragDropService.callEventCallback(scope, dragSettings.onDrag, event, ui);
}
});
} else {
element.draggable({disabled: true});
}
};
scope.$watch(function() { return scope.$eval(attrs.drag); }, updateDraggable);
updateDraggable();
}
};
}]).directive('jqyouiDroppable', ['ngDragDropService', function(ngDragDropService) {
return {
restrict: 'A',
priority: 1,
link: function(scope, element, attrs) {
var updateDroppable = function(newValue, oldValue) {
if (newValue) {
element
.droppable({disabled: false})
.droppable(scope.$eval(attrs.jqyouiOptions) || {})
.droppable({
over: function(event, ui) {
var dropSettings = scope.$eval(angular.element(this).attr('jqyoui-droppable')) || [];
ngDragDropService.callEventCallback(scope, dropSettings.onOver, event, ui);
},
out: function(event, ui) {
var dropSettings = scope.$eval(angular.element(this).attr('jqyoui-droppable')) || [];
ngDragDropService.callEventCallback(scope, dropSettings.onOut, event, ui);
},
drop: function(event, ui) {
if (angular.element(ui.draggable).ngattr('ng-model') && attrs.ngModel) {
ngDragDropService.invokeDrop(angular.element(ui.draggable), angular.element(this), event, ui);
} else {
ngDragDropService.callEventCallback(scope, (scope.$eval(angular.element(this).attr('jqyoui-droppable')) || []).onDrop, event, ui);
}
}
});
} else {
element.droppable({disabled: true});
}
};
scope.$watch(function() { return scope.$eval(attrs.drop); }, updateDroppable);
updateDroppable();
}
};
}]);
$.fn.ngattr = function(name, value) {
var element = angular.element(this).get(0);
return element.getAttribute(name) || element.getAttribute('data-' + name);
};
})(window, window.angular);
© 2015 - 2025 Weber Informatics LLC | Privacy Policy