Skip to content

Instantly share code, notes, and snippets.

@jdnichollsc
Created October 5, 2016 12:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jdnichollsc/4c1ae672bfbad6bc364aa42f4dacd38e to your computer and use it in GitHub Desktop.
Save jdnichollsc/4c1ae672bfbad6bc364aa42f4dacd38e to your computer and use it in GitHub Desktop.
Drag and Drop in Ionic
(function (Draggable, TweenLite) {
'use strict';
angular
.module('App')
.directive('draggable', draggable);
draggable.$inject = ['$ionicGesture', '$ionicListDelegate', '$timeout'];
function draggable($ionicGesture, $ionicListDelegate, $timeout) {
var directive = {
link: link,
restrict: 'A'
};
return directive;
function link(scope, element, attrs) {
var animation = TweenLite.to(element, 0.3, {
boxShadow: "rgba(0,0,0,0.2) 0px 16px 32px 0px",
force3D: true,
scale: 1.1,
paused: true
});
var dragger = new Draggable(element, {
type: "y",
bounds: element.parent()[0],
edgeResistance: 1,
onPress: sortablePress,
onDragStart: sortableDragStart,
onDrag: sortableDrag,
liveSnap: sortableSnap,
onDragEnd: sortableDragEnd
});
dragger.disable();
$ionicGesture.on('hold', function (e) {
dragger.enable();
$timeout(function(){
dragger.startDrag();
}, 50);
}, element, { hold_threshold: 20 });
function sortablePress() {
var t = this.target,
i = 0,
child = t;
while (child = child.previousSibling)
if (child.nodeType === 1) i++;
t.currentIndex = i;
t.currentHeight = t.offsetHeight;
t.kids = [].slice.call(t.parentNode.children); // convert to array
}
function sortableDragStart() {
TweenLite.set(this.target, { color: "#88CE02" });
animation.play();
this.update();
}
function sortableDrag() {
var t = this.target,
elements = t.kids.slice(), // clone
indexChange = Math.round(this.y / t.currentHeight),
bound1 = t.currentIndex,
bound2 = bound1 + indexChange;
if (bound1 < bound2) { // moved down
TweenLite.to(elements.splice(bound1 + 1, bound2 - bound1), 0.15, { yPercent: -100 });
TweenLite.to(elements, 0.15, { yPercent: 0 });
} else if (bound1 === bound2) {
elements.splice(bound1, 1);
TweenLite.to(elements, 0.15, { yPercent: 0 });
} else { // moved up
TweenLite.to(elements.splice(bound2, bound1 - bound2), 0.15, { yPercent: 100 });
TweenLite.to(elements, 0.15, { yPercent: 0 });
}
}
function sortableSnap(y) {
var h = this.target.currentHeight;
return Math.round(y / h) * h;
}
function sortableDragEnd() {
var t = this.target,
max = t.kids.length - 1,
newIndex = Math.round(this.y / t.currentHeight);
newIndex += (newIndex < 0 ? -1 : 0) + t.currentIndex;
if (newIndex === max) {
t.parentNode.appendChild(t);
} else {
t.parentNode.insertBefore(t, t.kids[newIndex + 1]);
}
TweenLite.set(t.kids, { yPercent: 0, overwrite: "all" });
TweenLite.set(t, { y: 0, color: "" });
animation.reverse();
dragger.disable();
}
}
}
})(Draggable, TweenLite);
<script src="//cdnjs.cloudflare.com/ajax/libs/gsap/1.19.0/TweenMax.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/gsap/1.19.0/utils/Draggable.min.js"></script>
<ion-list can-swipe="true">
<ion-item draggable ng-repeat="user in users">
{{user.Name}}
<ion-option-button class="button-assertive">Edit</ion-option-button>
</ion-item>
</ion-list>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment