angular-pack 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +23 -0
- data/Gemfile +4 -0
- data/MIT-LICENSE +22 -0
- data/README.md +46 -0
- data/Rakefile +2 -0
- data/angular-pack.gemspec +17 -0
- data/lib/angular-pack.rb +6 -0
- data/lib/angular/pack/version.rb +5 -0
- data/vendor/assets/javascripts/angular-animate.js +1483 -0
- data/vendor/assets/javascripts/angular-cookies.js +202 -0
- data/vendor/assets/javascripts/angular-loader.js +410 -0
- data/vendor/assets/javascripts/angular-mocks.js +2165 -0
- data/vendor/assets/javascripts/angular-resource.js +594 -0
- data/vendor/assets/javascripts/angular-route.js +920 -0
- data/vendor/assets/javascripts/angular-sanitize.js +622 -0
- data/vendor/assets/javascripts/angular-scenario.js +32566 -0
- data/vendor/assets/javascripts/angular-touch.js +563 -0
- data/vendor/assets/javascripts/angular-ui-router.js +3223 -0
- data/vendor/assets/javascripts/angular.js +20560 -0
- data/vendor/assets/javascripts/es5-shim.js +1402 -0
- data/vendor/assets/javascripts/ng-grid.js +3613 -0
- data/vendor/assets/javascripts/ui-bootstrap-tpls.js +3677 -0
- data/vendor/assets/javascripts/ui-bootstrap.js +3427 -0
- data/vendor/assets/javascripts/ui-date.js +121 -0
- data/vendor/assets/javascripts/ui-map.js +128 -0
- data/vendor/assets/javascripts/ui-sortable.js +211 -0
- data/vendor/assets/javascripts/ui-utils.js +2055 -0
- data/vendor/assets/stylesheets/angular-csp.css +13 -0
- data/vendor/assets/stylesheets/ng-grid.css +439 -0
- metadata +73 -0
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/*global angular */
|
|
2
|
+
/*
|
|
3
|
+
jQuery UI Datepicker plugin wrapper
|
|
4
|
+
|
|
5
|
+
@note If ≤ IE8 make sure you have a polyfill for Date.toISOString()
|
|
6
|
+
@param [ui-date] {object} Options to pass to $.fn.datepicker() merged onto uiDateConfig
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
angular.module('ui.date', [])
|
|
10
|
+
|
|
11
|
+
.constant('uiDateConfig', {})
|
|
12
|
+
|
|
13
|
+
.directive('uiDate', ['uiDateConfig', function (uiDateConfig) {
|
|
14
|
+
'use strict';
|
|
15
|
+
var options;
|
|
16
|
+
options = {};
|
|
17
|
+
angular.extend(options, uiDateConfig);
|
|
18
|
+
return {
|
|
19
|
+
require:'?ngModel',
|
|
20
|
+
link:function (scope, element, attrs, controller) {
|
|
21
|
+
var getOptions = function () {
|
|
22
|
+
return angular.extend({}, uiDateConfig, scope.$eval(attrs.uiDate));
|
|
23
|
+
};
|
|
24
|
+
var initDateWidget = function () {
|
|
25
|
+
var showing = false;
|
|
26
|
+
var opts = getOptions();
|
|
27
|
+
|
|
28
|
+
// If we have a controller (i.e. ngModelController) then wire it up
|
|
29
|
+
if (controller) {
|
|
30
|
+
|
|
31
|
+
// Set the view value in a $apply block when users selects
|
|
32
|
+
// (calling directive user's function too if provided)
|
|
33
|
+
var _onSelect = opts.onSelect || angular.noop;
|
|
34
|
+
opts.onSelect = function (value, picker) {
|
|
35
|
+
scope.$apply(function() {
|
|
36
|
+
showing = true;
|
|
37
|
+
controller.$setViewValue(element.datepicker("getDate"));
|
|
38
|
+
_onSelect(value, picker);
|
|
39
|
+
element.blur();
|
|
40
|
+
});
|
|
41
|
+
};
|
|
42
|
+
opts.beforeShow = function() {
|
|
43
|
+
showing = true;
|
|
44
|
+
};
|
|
45
|
+
opts.onClose = function(value, picker) {
|
|
46
|
+
showing = false;
|
|
47
|
+
};
|
|
48
|
+
element.on('blur', function() {
|
|
49
|
+
if ( !showing ) {
|
|
50
|
+
scope.$apply(function() {
|
|
51
|
+
element.datepicker("setDate", element.datepicker("getDate"));
|
|
52
|
+
controller.$setViewValue(element.datepicker("getDate"));
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// Update the date picker when the model changes
|
|
58
|
+
controller.$render = function () {
|
|
59
|
+
var date = controller.$viewValue;
|
|
60
|
+
if ( angular.isDefined(date) && date !== null && !angular.isDate(date) ) {
|
|
61
|
+
throw new Error('ng-Model value must be a Date object - currently it is a ' + typeof date + ' - use ui-date-format to convert it from a string');
|
|
62
|
+
}
|
|
63
|
+
element.datepicker("setDate", date);
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
// If we don't destroy the old one it doesn't update properly when the config changes
|
|
67
|
+
element.datepicker('destroy');
|
|
68
|
+
// Create the new datepicker widget
|
|
69
|
+
element.datepicker(opts);
|
|
70
|
+
if ( controller ) {
|
|
71
|
+
// Force a render to override whatever is in the input text box
|
|
72
|
+
controller.$render();
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
// Watch for changes to the directives options
|
|
76
|
+
scope.$watch(getOptions, initDateWidget, true);
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
])
|
|
81
|
+
|
|
82
|
+
.constant('uiDateFormatConfig', '')
|
|
83
|
+
|
|
84
|
+
.directive('uiDateFormat', ['uiDateFormatConfig', function(uiDateFormatConfig) {
|
|
85
|
+
var directive = {
|
|
86
|
+
require:'ngModel',
|
|
87
|
+
link: function(scope, element, attrs, modelCtrl) {
|
|
88
|
+
var dateFormat = attrs.uiDateFormat || uiDateFormatConfig;
|
|
89
|
+
if ( dateFormat ) {
|
|
90
|
+
// Use the datepicker with the attribute value as the dateFormat string to convert to and from a string
|
|
91
|
+
modelCtrl.$formatters.push(function(value) {
|
|
92
|
+
if (angular.isString(value) ) {
|
|
93
|
+
return jQuery.datepicker.parseDate(dateFormat, value);
|
|
94
|
+
}
|
|
95
|
+
return null;
|
|
96
|
+
});
|
|
97
|
+
modelCtrl.$parsers.push(function(value){
|
|
98
|
+
if (value) {
|
|
99
|
+
return jQuery.datepicker.formatDate(dateFormat, value);
|
|
100
|
+
}
|
|
101
|
+
return null;
|
|
102
|
+
});
|
|
103
|
+
} else {
|
|
104
|
+
// Default to ISO formatting
|
|
105
|
+
modelCtrl.$formatters.push(function(value) {
|
|
106
|
+
if (angular.isString(value) ) {
|
|
107
|
+
return new Date(value);
|
|
108
|
+
}
|
|
109
|
+
return null;
|
|
110
|
+
});
|
|
111
|
+
modelCtrl.$parsers.push(function(value){
|
|
112
|
+
if (value) {
|
|
113
|
+
return value.toISOString();
|
|
114
|
+
}
|
|
115
|
+
return null;
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
return directive;
|
|
121
|
+
}]);
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
(function () {
|
|
4
|
+
var app = angular.module('ui.map', ['ui.event']);
|
|
5
|
+
|
|
6
|
+
//Setup map events from a google map object to trigger on a given element too,
|
|
7
|
+
//then we just use ui-event to catch events from an element
|
|
8
|
+
function bindMapEvents(scope, eventsStr, googleObject, element) {
|
|
9
|
+
angular.forEach(eventsStr.split(' '), function (eventName) {
|
|
10
|
+
//Prefix all googlemap events with 'map-', so eg 'click'
|
|
11
|
+
//for the googlemap doesn't interfere with a normal 'click' event
|
|
12
|
+
window.google.maps.event.addListener(googleObject, eventName, function (event) {
|
|
13
|
+
element.triggerHandler('map-' + eventName, event);
|
|
14
|
+
//We create an $apply if it isn't happening. we need better support for this
|
|
15
|
+
//We don't want to use timeout because tons of these events fire at once,
|
|
16
|
+
//and we only need one $apply
|
|
17
|
+
if (!scope.$$phase){ scope.$apply();}
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
app.value('uiMapConfig', {}).directive('uiMap',
|
|
23
|
+
['uiMapConfig', '$parse', function (uiMapConfig, $parse) {
|
|
24
|
+
|
|
25
|
+
var mapEvents = 'bounds_changed center_changed click dblclick drag dragend ' +
|
|
26
|
+
'dragstart heading_changed idle maptypeid_changed mousemove mouseout ' +
|
|
27
|
+
'mouseover projection_changed resize rightclick tilesloaded tilt_changed ' +
|
|
28
|
+
'zoom_changed';
|
|
29
|
+
var options = uiMapConfig || {};
|
|
30
|
+
|
|
31
|
+
return {
|
|
32
|
+
restrict: 'A',
|
|
33
|
+
//doesn't work as E for unknown reason
|
|
34
|
+
link: function (scope, elm, attrs) {
|
|
35
|
+
var opts = angular.extend({}, options, scope.$eval(attrs.uiOptions));
|
|
36
|
+
var map = new window.google.maps.Map(elm[0], opts);
|
|
37
|
+
var model = $parse(attrs.uiMap);
|
|
38
|
+
|
|
39
|
+
//Set scope variable for the map
|
|
40
|
+
model.assign(scope, map);
|
|
41
|
+
|
|
42
|
+
bindMapEvents(scope, mapEvents, map, elm);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
}]);
|
|
46
|
+
|
|
47
|
+
app.value('uiMapInfoWindowConfig', {}).directive('uiMapInfoWindow',
|
|
48
|
+
['uiMapInfoWindowConfig', '$parse', '$compile', function (uiMapInfoWindowConfig, $parse, $compile) {
|
|
49
|
+
|
|
50
|
+
var infoWindowEvents = 'closeclick content_change domready ' +
|
|
51
|
+
'position_changed zindex_changed';
|
|
52
|
+
var options = uiMapInfoWindowConfig || {};
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
link: function (scope, elm, attrs) {
|
|
56
|
+
var opts = angular.extend({}, options, scope.$eval(attrs.uiOptions));
|
|
57
|
+
opts.content = elm[0];
|
|
58
|
+
var model = $parse(attrs.uiMapInfoWindow);
|
|
59
|
+
var infoWindow = model(scope);
|
|
60
|
+
|
|
61
|
+
if (!infoWindow) {
|
|
62
|
+
infoWindow = new window.google.maps.InfoWindow(opts);
|
|
63
|
+
model.assign(scope, infoWindow);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
bindMapEvents(scope, infoWindowEvents, infoWindow, elm);
|
|
67
|
+
|
|
68
|
+
/* The info window's contents dont' need to be on the dom anymore,
|
|
69
|
+
google maps has them stored. So we just replace the infowindow element
|
|
70
|
+
with an empty div. (we don't just straight remove it from the dom because
|
|
71
|
+
straight removing things from the dom can mess up angular) */
|
|
72
|
+
elm.replaceWith('<div></div>');
|
|
73
|
+
|
|
74
|
+
//Decorate infoWindow.open to $compile contents before opening
|
|
75
|
+
var _open = infoWindow.open;
|
|
76
|
+
infoWindow.open = function open(a1, a2, a3, a4, a5, a6) {
|
|
77
|
+
$compile(elm.contents())(scope);
|
|
78
|
+
_open.call(infoWindow, a1, a2, a3, a4, a5, a6);
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
}]);
|
|
83
|
+
|
|
84
|
+
/*
|
|
85
|
+
* Map overlay directives all work the same. Take map marker for example
|
|
86
|
+
* <ui-map-marker="myMarker"> will $watch 'myMarker' and each time it changes,
|
|
87
|
+
* it will hook up myMarker's events to the directive dom element. Then
|
|
88
|
+
* ui-event will be able to catch all of myMarker's events. Super simple.
|
|
89
|
+
*/
|
|
90
|
+
function mapOverlayDirective(directiveName, events) {
|
|
91
|
+
app.directive(directiveName, [function () {
|
|
92
|
+
return {
|
|
93
|
+
restrict: 'A',
|
|
94
|
+
link: function (scope, elm, attrs) {
|
|
95
|
+
scope.$watch(attrs[directiveName], function (newObject) {
|
|
96
|
+
if (newObject) {
|
|
97
|
+
bindMapEvents(scope, events, newObject, elm);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
}]);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
mapOverlayDirective('uiMapMarker',
|
|
106
|
+
'animation_changed click clickable_changed cursor_changed ' +
|
|
107
|
+
'dblclick drag dragend draggable_changed dragstart flat_changed icon_changed ' +
|
|
108
|
+
'mousedown mouseout mouseover mouseup position_changed rightclick ' +
|
|
109
|
+
'shadow_changed shape_changed title_changed visible_changed zindex_changed');
|
|
110
|
+
|
|
111
|
+
mapOverlayDirective('uiMapPolyline',
|
|
112
|
+
'click dblclick mousedown mousemove mouseout mouseover mouseup rightclick');
|
|
113
|
+
|
|
114
|
+
mapOverlayDirective('uiMapPolygon',
|
|
115
|
+
'click dblclick mousedown mousemove mouseout mouseover mouseup rightclick');
|
|
116
|
+
|
|
117
|
+
mapOverlayDirective('uiMapRectangle',
|
|
118
|
+
'bounds_changed click dblclick mousedown mousemove mouseout mouseover ' +
|
|
119
|
+
'mouseup rightclick');
|
|
120
|
+
|
|
121
|
+
mapOverlayDirective('uiMapCircle',
|
|
122
|
+
'center_changed click dblclick mousedown mousemove ' +
|
|
123
|
+
'mouseout mouseover mouseup radius_changed rightclick');
|
|
124
|
+
|
|
125
|
+
mapOverlayDirective('uiMapGroundOverlay',
|
|
126
|
+
'click dblclick');
|
|
127
|
+
|
|
128
|
+
})();
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/*
|
|
2
|
+
jQuery UI Sortable plugin wrapper
|
|
3
|
+
|
|
4
|
+
@param [ui-sortable] {object} Options to pass to $.fn.sortable() merged onto ui.config
|
|
5
|
+
*/
|
|
6
|
+
angular.module('ui.sortable', [])
|
|
7
|
+
.value('uiSortableConfig',{})
|
|
8
|
+
.directive('uiSortable', [
|
|
9
|
+
'uiSortableConfig', '$timeout', '$log',
|
|
10
|
+
function(uiSortableConfig, $timeout, $log) {
|
|
11
|
+
return {
|
|
12
|
+
require: '?ngModel',
|
|
13
|
+
link: function(scope, element, attrs, ngModel) {
|
|
14
|
+
var savedNodes;
|
|
15
|
+
|
|
16
|
+
function combineCallbacks(first,second){
|
|
17
|
+
if(second && (typeof second === 'function')) {
|
|
18
|
+
return function(e, ui) {
|
|
19
|
+
first(e, ui);
|
|
20
|
+
second(e, ui);
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
return first;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
var opts = {};
|
|
27
|
+
|
|
28
|
+
var callbacks = {
|
|
29
|
+
receive: null,
|
|
30
|
+
remove:null,
|
|
31
|
+
start:null,
|
|
32
|
+
stop:null,
|
|
33
|
+
update:null
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
angular.extend(opts, uiSortableConfig);
|
|
37
|
+
|
|
38
|
+
if (ngModel) {
|
|
39
|
+
|
|
40
|
+
// When we add or remove elements, we need the sortable to 'refresh'
|
|
41
|
+
// so it can find the new/removed elements.
|
|
42
|
+
scope.$watch(attrs.ngModel+'.length', function() {
|
|
43
|
+
// Timeout to let ng-repeat modify the DOM
|
|
44
|
+
$timeout(function() {
|
|
45
|
+
// ensure that the jquery-ui-sortable widget instance
|
|
46
|
+
// is still bound to the directive's element
|
|
47
|
+
if (!!element.data('ui-sortable')) {
|
|
48
|
+
element.sortable('refresh');
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
callbacks.start = function(e, ui) {
|
|
54
|
+
// Save the starting position of dragged item
|
|
55
|
+
ui.item.sortable = {
|
|
56
|
+
index: ui.item.index(),
|
|
57
|
+
cancel: function () {
|
|
58
|
+
ui.item.sortable._isCanceled = true;
|
|
59
|
+
},
|
|
60
|
+
isCanceled: function () {
|
|
61
|
+
return ui.item.sortable._isCanceled;
|
|
62
|
+
},
|
|
63
|
+
_isCanceled: false
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
callbacks.activate = function(/*e, ui*/) {
|
|
68
|
+
// We need to make a copy of the current element's contents so
|
|
69
|
+
// we can restore it after sortable has messed it up.
|
|
70
|
+
// This is inside activate (instead of start) in order to save
|
|
71
|
+
// both lists when dragging between connected lists.
|
|
72
|
+
savedNodes = element.contents();
|
|
73
|
+
|
|
74
|
+
// If this list has a placeholder (the connected lists won't),
|
|
75
|
+
// don't inlcude it in saved nodes.
|
|
76
|
+
var placeholder = element.sortable('option','placeholder');
|
|
77
|
+
|
|
78
|
+
// placeholder.element will be a function if the placeholder, has
|
|
79
|
+
// been created (placeholder will be an object). If it hasn't
|
|
80
|
+
// been created, either placeholder will be false if no
|
|
81
|
+
// placeholder class was given or placeholder.element will be
|
|
82
|
+
// undefined if a class was given (placeholder will be a string)
|
|
83
|
+
if (placeholder && placeholder.element && typeof placeholder.element === 'function') {
|
|
84
|
+
var phElement = placeholder.element();
|
|
85
|
+
// workaround for jquery ui 1.9.x,
|
|
86
|
+
// not returning jquery collection
|
|
87
|
+
if (!phElement.jquery) {
|
|
88
|
+
phElement = angular.element(phElement);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// exact match with the placeholder's class attribute to handle
|
|
92
|
+
// the case that multiple connected sortables exist and
|
|
93
|
+
// the placehoilder option equals the class of sortable items
|
|
94
|
+
var excludes = element.find('[class="' + phElement.attr('class') + '"]');
|
|
95
|
+
|
|
96
|
+
savedNodes = savedNodes.not(excludes);
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
callbacks.update = function(e, ui) {
|
|
101
|
+
// Save current drop position but only if this is not a second
|
|
102
|
+
// update that happens when moving between lists because then
|
|
103
|
+
// the value will be overwritten with the old value
|
|
104
|
+
if(!ui.item.sortable.received) {
|
|
105
|
+
ui.item.sortable.dropindex = ui.item.index();
|
|
106
|
+
ui.item.sortable.droptarget = ui.item.parent();
|
|
107
|
+
|
|
108
|
+
// Cancel the sort (let ng-repeat do the sort for us)
|
|
109
|
+
// Don't cancel if this is the received list because it has
|
|
110
|
+
// already been canceled in the other list, and trying to cancel
|
|
111
|
+
// here will mess up the DOM.
|
|
112
|
+
element.sortable('cancel');
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Put the nodes back exactly the way they started (this is very
|
|
116
|
+
// important because ng-repeat uses comment elements to delineate
|
|
117
|
+
// the start and stop of repeat sections and sortable doesn't
|
|
118
|
+
// respect their order (even if we cancel, the order of the
|
|
119
|
+
// comments are still messed up).
|
|
120
|
+
if (element.sortable('option','helper') === 'clone') {
|
|
121
|
+
// restore all the savedNodes except .ui-sortable-helper element
|
|
122
|
+
// (which is placed last). That way it will be garbage collected.
|
|
123
|
+
savedNodes = savedNodes.not(savedNodes.last());
|
|
124
|
+
}
|
|
125
|
+
savedNodes.appendTo(element);
|
|
126
|
+
|
|
127
|
+
// If received is true (an item was dropped in from another list)
|
|
128
|
+
// then we add the new item to this list otherwise wait until the
|
|
129
|
+
// stop event where we will know if it was a sort or item was
|
|
130
|
+
// moved here from another list
|
|
131
|
+
if(ui.item.sortable.received && !ui.item.sortable.isCanceled()) {
|
|
132
|
+
scope.$apply(function () {
|
|
133
|
+
ngModel.$modelValue.splice(ui.item.sortable.dropindex, 0,
|
|
134
|
+
ui.item.sortable.moved);
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
callbacks.stop = function(e, ui) {
|
|
140
|
+
// If the received flag hasn't be set on the item, this is a
|
|
141
|
+
// normal sort, if dropindex is set, the item was moved, so move
|
|
142
|
+
// the items in the list.
|
|
143
|
+
if(!ui.item.sortable.received &&
|
|
144
|
+
('dropindex' in ui.item.sortable) &&
|
|
145
|
+
!ui.item.sortable.isCanceled()) {
|
|
146
|
+
|
|
147
|
+
scope.$apply(function () {
|
|
148
|
+
ngModel.$modelValue.splice(
|
|
149
|
+
ui.item.sortable.dropindex, 0,
|
|
150
|
+
ngModel.$modelValue.splice(ui.item.sortable.index, 1)[0]);
|
|
151
|
+
});
|
|
152
|
+
} else {
|
|
153
|
+
// if the item was not moved, then restore the elements
|
|
154
|
+
// so that the ngRepeat's comment are correct.
|
|
155
|
+
if((!('dropindex' in ui.item.sortable) || ui.item.sortable.isCanceled()) && element.sortable('option','helper') !== 'clone') {
|
|
156
|
+
savedNodes.appendTo(element);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
callbacks.receive = function(e, ui) {
|
|
162
|
+
// An item was dropped here from another list, set a flag on the
|
|
163
|
+
// item.
|
|
164
|
+
ui.item.sortable.received = true;
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
callbacks.remove = function(e, ui) {
|
|
168
|
+
// Remove the item from this list's model and copy data into item,
|
|
169
|
+
// so the next list can retrive it
|
|
170
|
+
if (!ui.item.sortable.isCanceled()) {
|
|
171
|
+
scope.$apply(function () {
|
|
172
|
+
ui.item.sortable.moved = ngModel.$modelValue.splice(
|
|
173
|
+
ui.item.sortable.index, 1)[0];
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
scope.$watch(attrs.uiSortable, function(newVal /*, oldVal*/) {
|
|
179
|
+
// ensure that the jquery-ui-sortable widget instance
|
|
180
|
+
// is still bound to the directive's element
|
|
181
|
+
if (!!element.data('ui-sortable')) {
|
|
182
|
+
angular.forEach(newVal, function(value, key) {
|
|
183
|
+
if(callbacks[key]) {
|
|
184
|
+
if( key === 'stop' ){
|
|
185
|
+
// call apply after stop
|
|
186
|
+
value = combineCallbacks(
|
|
187
|
+
value, function() { scope.$apply(); });
|
|
188
|
+
}
|
|
189
|
+
// wrap the callback
|
|
190
|
+
value = combineCallbacks(callbacks[key], value);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
element.sortable('option', key, value);
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
}, true);
|
|
197
|
+
|
|
198
|
+
angular.forEach(callbacks, function(value, key) {
|
|
199
|
+
opts[key] = combineCallbacks(value, opts[key]);
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
} else {
|
|
203
|
+
$log.info('ui.sortable: ngModel not provided!', element);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// Create sortable
|
|
207
|
+
element.sortable(opts);
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
]);
|