Skip to content

Update angular dragdrop to 1.0.6 #3

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/angular-dragdrop-rails/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module AngularDragdrop
module Rails
VERSION = "1.0.2"
VERSION = "1.0.6"
end
end
154 changes: 111 additions & 43 deletions vendor/assets/javascripts/angular-dragdrop-original.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,39 @@
* Implementing Drag and Drop functionality in AngularJS is easier than ever.
* Demo: http://codef0rmer.github.com/angular-dragdrop/
*
* @version 1.0.2
* @version 1.0.6
*
* (c) 2013 Amit Gharat a.k.a codef0rmer <[email protected]> - amitgharat.wordpress.com
*/

(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) {
if (!callbackName) {
return;
}
var args = [event, ui];
var match = callbackName.match(/^(.+)\((.+)\)$/);
if (match !== null) {
callbackName = match[1];
values = eval('[' + match[0].replace(/^(.+)\(/, '').replace(/\)/, '') + ']');
args.push.apply(args, values);
if (!callbackName) return;

var objExtract = extract(callbackName),
callback = objExtract.callback,
constructor = objExtract.constructor,
args = [event, ui].concat(objExtract.args);

// call either $scoped method i.e. $scope.dropCallback or constructor's method i.e. this.dropCallback
scope.$apply((scope[callback] || scope[constructor][callback]).apply(scope, args));

function extract(callbackName) {
var atStartBracket = callbackName.indexOf('(') !== -1 ? callbackName.indexOf('(') : callbackName.length,
atEndBracket = callbackName.lastIndexOf(')') !== -1 ? callbackName.lastIndexOf(')') : callbackName.length,
args = callbackName.substring(atStartBracket + 1, atEndBracket), // matching function arguments inside brackets
constructor = callbackName.match(/^[^.]+.\s*/)[0].slice(0, -1); // matching a string upto a dot to check ctrl as syntax
constructor = scope[constructor] && typeof scope[constructor].constructor === 'function' ? constructor : null;

return {
callback: callbackName.substring(constructor && constructor.length + 1 || 0, atStartBracket),
args: (args && args.split(',') || []).map(function(item) { return $parse(item)(scope); }),
constructor: constructor
}
}
scope[callbackName].apply(scope, args);
};

this.invokeDrop = function ($draggable, $droppable, event, ui) {
Expand All @@ -56,14 +71,18 @@ var jqyoui = angular.module('ngDragDrop', []).service('ngDragDropService', ['$ti
droppableScope = $droppable.scope(),
draggableScope = $draggable.scope();

dragModel = $draggable.attr('ng-model');
dropModel = $droppable.attr('ng-model');
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')) || [];
$droppableDraggable = $droppable.find('[jqyoui-draggable]:last,[data-jqyoui-draggable]:last');
dropSettings = droppableScope.$eval($droppable.attr('jqyoui-droppable') || $droppable.attr('data-jqyoui-droppable')) || [];
dragSettings = draggableScope.$eval($draggable.attr('jqyoui-draggable') || $draggable.attr('data-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;
Expand All @@ -78,23 +97,25 @@ var jqyoui = angular.module('ngDragDrop', []).service('ngDragDropService', ['$ti

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() {
this.move($droppableDraggable.length > 0 && !dropSettings.multiple ? $droppableDraggable : [], $draggable.parent('[jqyoui-droppable],[data-jqyoui-droppable]'), jqyoui.startXY, 'fast', dropSettings, angular.bind(this, function() {
$timeout(angular.bind(this, function() {
// Do not move this into move() to avoid flickering issue
$draggable.css({'position': 'relative', 'left': '', 'top': ''});
$droppableDraggable.css({'position': 'relative', 'left': '', 'top': ''});
// Angular v1.2 uses ng-hide to hide an element not display property
// so we've to manually remove display:none set in this.move()
$droppableDraggable.css({'position': 'relative', 'left': '', 'top': '', 'display': ''});

this.mutateDraggable(draggableScope, dropSettings, dragSettings, dragModel, dropModel, dropItem, $draggable);
this.mutateDroppable(droppableScope, dropSettings, dragSettings, dropModel, dragItem, jqyoui_pos);
this.callEventCallback(droppableScope, dropSettings.onDrop, event, ui);
}.bind(this));
}.bind(this));
}));
}));
} else {
$timeout(function() {
$timeout(angular.bind(this, function() {
this.mutateDraggable(draggableScope, dropSettings, dragSettings, dragModel, dropModel, dropItem, $draggable);
this.mutateDroppable(droppableScope, dropSettings, dragSettings, dropModel, dragItem, jqyoui_pos);
this.callEventCallback(droppableScope, dropSettings.onDrop, event, ui);
}.bind(this));
}));
}
};

Expand All @@ -110,33 +131,42 @@ var jqyoui = angular.module('ngDragDrop', []).service('ngDragDropService', ['$ti

var zIndex = 9999,
fromPos = $fromEl.offset(),
wasVisible = $toEl && $toEl.is(':visible');
wasVisible = $toEl && $toEl.is(':visible'),
hadNgHideCls = $toEl.hasClass('ng-hide');

if (toPos === null && $toEl.length > 0) {
if ($toEl.attr('jqyoui-draggable') !== undefined && $toEl.attr('ng-model') !== undefined && $toEl.is(':visible') && dropSettings && dropSettings.multiple) {
if (($toEl.attr('jqyoui-draggable') || $toEl.attr('data-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 {
// Angular v1.2 uses ng-hide to hide an element
// so we've to remove it in order to grab its position
if (hadNgHideCls) $toEl.removeClass('ng-hide');
toPos = $toEl.css({'visibility': 'hidden', 'display': 'block'}).offset();
$toEl.css({'visibility': '','display': wasVisible ? '' : 'none'});
$toEl.css({'visibility': '','display': wasVisible ? 'block' : 'none'});
}
}

$fromEl.css({'position': 'absolute', 'z-index': zIndex})
.css(fromPos)
.animate(toPos, duration, function() {
// Angular v1.2 uses ng-hide to hide an element
// and as we remove it above, we've to put it back to
// hide the element (while swapping) if it was hidden already
// because we remove the display:none in this.invokeDrop()
if (hadNgHideCls) $toEl.addClass('ng-hide');
if (callback) callback();
});
};

this.mutateDroppable = function(scope, dropSettings, dragSettings, dropModel, dragItem, jqyoui_pos) {
var dropModelValue = scope.$eval(dropModel);

scope.__dragItem = dragItem;
scope.dndDragItem = dragItem;

if (angular.isArray(dropModelValue)) {
if (dropSettings && dropSettings.index >= 0) {
Expand All @@ -148,25 +178,25 @@ var jqyoui = angular.module('ngDragDrop', []).service('ngDragDropService', ['$ti
dropModelValue[dropModelValue.length - 1]['jqyoui_pos'] = jqyoui_pos;
}
} else {
$parse(dropModel + ' = __dragItem')(scope);
$parse(dropModel + ' = dndDragItem')(scope);
if (dragSettings && dragSettings.placeholder === true) {
dropModelValue['jqyoui_pos'] = jqyoui_pos;
}
}
};

this.mutateDraggable = function(scope, dropSettings, dragSettings, dragModel, dropModel, dropItem, $draggable) {
var isEmpty = $.isEmptyObject(angular.copy(dropItem)),
var isEmpty = angular.equals(angular.copy(dropItem), {}),
dragModelValue = scope.$eval(dragModel);

scope.__dropItem = dropItem;
scope.dndDropItem = 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);
$parse(dragModel + ' = dndDropItem')(scope);
}
}
} else {
Expand All @@ -181,36 +211,55 @@ var jqyoui = angular.module('ngDragDrop', []).service('ngDragDropService', ['$ti
} 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);
$parse(dragModel + ' = dndDropItem')(scope);
if (scope.$parent) {
$parse(dragModel + ' = __dropItem')(scope.$parent);
$parse(dragModel + ' = dndDropItem')(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 dragSettings, jqyouiOptions, zIndex;
var updateDraggable = function(newValue, oldValue) {
if (newValue) {
dragSettings = scope.$eval(element.attr('jqyoui-draggable')) || [];
dragSettings = scope.$eval(element.attr('jqyoui-draggable') || element.attr('data-jqyoui-draggable')) || {};
jqyouiOptions = scope.$eval(attrs.jqyouiOptions) || {};
element
.draggable({disabled: false})
.draggable(scope.$eval(attrs.jqyouiOptions) || {})
.draggable(jqyouiOptions)
.draggable({
start: function(event, ui) {
zIndex = $(this).css('z-index');
$(this).css('z-index', 99999);
jqyoui.startXY = $(this).offset();
zIndex = angular.element(jqyouiOptions.helper ? ui.helper : this).css('z-index');
angular.element(jqyouiOptions.helper ? ui.helper : this).css('z-index', 9999);
jqyoui.startXY = angular.element(this).offset();
ngDragDropService.callEventCallback(scope, dragSettings.onStart, event, ui);
},
stop: function(event, ui) {
$(this).css('z-index', zIndex);
angular.element(jqyouiOptions.helper ? ui.helper : this).css('z-index', zIndex);
ngDragDropService.callEventCallback(scope, dragSettings.onStop, event, ui);
},
drag: function(event, ui) {
Expand All @@ -223,29 +272,37 @@ var jqyoui = angular.module('ngDragDrop', []).service('ngDragDropService', ['$ti
};
scope.$watch(function() { return scope.$eval(attrs.drag); }, updateDraggable);
updateDraggable();

element.on('$destroy', function() {
element.draggable('destroy');
});
}
};
}]).directive('jqyouiDroppable', ['ngDragDropService', function(ngDragDropService) {
return {
restrict: 'A',
priority: 1,
link: function(scope, element, attrs) {
var dropSettings;
var updateDroppable = function(newValue, oldValue) {
if (newValue) {
dropSettings = scope.$eval(angular.element(this).attr('jqyoui-droppable') || angular.element(this).attr('data-jqyoui-droppable')) || {};
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) {
ngDragDropService.invokeDrop(angular.element(ui.draggable), angular.element(this), 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, dropSettings.onDrop, event, ui);
}
}
});
} else {
Expand All @@ -255,6 +312,17 @@ var jqyoui = angular.module('ngDragDrop', []).service('ngDragDropService', ['$ti

scope.$watch(function() { return scope.$eval(attrs.drop); }, updateDroppable);
updateDroppable();

element.on('$destroy', function() {
element.droppable('destroy');
});
}
};
}]);

$.fn.ngattr = function(name, value) {
var element = angular.element(this).get(0);

return element.getAttribute(name) || element.getAttribute('data-' + name);
};
})(window, window.angular);