Files
andors-trail/AndorsTrailEdit/lib/ng-sortable.js
2013-11-24 11:29:53 +01:00

124 lines
4.1 KiB
JavaScript

/*
jQuery UI Sortable plugin wrapper
https://github.com/angular-ui/ui-sortable
@param [ui-sortable] {object} Options to pass to $.fn.sortable() merged onto ui.config
*/
angular.module('ui.sortable', [])
.value('uiSortableConfig',{})
.directive('uiSortable', [ 'uiSortableConfig', '$log',
function(uiSortableConfig, log) {
return {
require: '?ngModel',
link: function(scope, element, attrs, ngModel) {
function combineCallbacks(first,second){
if( second && (typeof second === "function") ){
return function(e,ui){
first(e,ui);
second(e,ui);
};
}
return first;
}
var opts = {};
var callbacks = {
receive: null,
remove:null,
start:null,
stop:null,
update:null
};
var apply = function(e, ui) {
if (ui.item.sortable.resort || ui.item.sortable.relocate) {
scope.$apply();
}
};
angular.extend(opts, uiSortableConfig);
if (ngModel) {
ngModel.$render = function() {
element.sortable( "refresh" );
};
callbacks.start = function(e, ui) {
// Save position of dragged item
ui.item.sortable = { index: ui.item.index() };
};
callbacks.update = function(e, ui) {
// For some reason the reference to ngModel in stop() is wrong
ui.item.sortable.resort = ngModel;
};
callbacks.receive = function(e, ui) {
ui.item.sortable.relocate = true;
// added item to array into correct position and set up flag
ngModel.$modelValue.splice(ui.item.index(), 0, ui.item.sortable.moved);
};
callbacks.remove = function(e, ui) {
// copy data into item
if (ngModel.$modelValue.length === 1) {
ui.item.sortable.moved = ngModel.$modelValue.splice(0, 1)[0];
} else {
ui.item.sortable.moved = ngModel.$modelValue.splice(ui.item.sortable.index, 1)[0];
}
};
callbacks.stop = function(e, ui) {
// digest all prepared changes
if (ui.item.sortable.resort && !ui.item.sortable.relocate) {
// Fetch saved and current position of dropped element
var end, start;
start = ui.item.sortable.index;
end = ui.item.index();
// Reorder array and apply change to scope
ui.item.sortable.resort.$modelValue.splice(end, 0, ui.item.sortable.resort.$modelValue.splice(start, 1)[0]);
}
};
scope.$watch(attrs.uiSortable, function(newVal, oldVal){
angular.forEach(newVal, function(value, key){
if( callbacks[key] ){
// wrap the callback
value = combineCallbacks( callbacks[key], value );
if ( key === 'stop' ){
// call apply after stop
value = combineCallbacks( value, apply );
}
}
element.sortable('option', key, value);
});
}, true);
angular.forEach(callbacks, function(value, key ){
opts[key] = combineCallbacks(value, opts[key]);
});
// call apply after stop
opts.stop = combineCallbacks( opts.stop, apply );
} else {
log.info('ui.sortable: ngModel not provided!', element);
}
// Create sortable
element.sortable(opts);
}
};
}
]);