Drag And Drop Experiments

by Ryan

HTML

<script src="https://code.jquery.com/jquery-1.9.1.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.12/angular.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.12/angular-animate.js"></script>
<div ng-app="app" ng-controller="MainController">
    
    <div style="width: 300px; float: left;">

        <div x-ng-repeat="e in elements" class="animate-repeat">
            <div class="dropzone" x-drag-target x-model="$index" x-drop="onDrop(src, dest)"></div>
            <div class="element draggable" x-draggable x-model="{index: $index, object: e}">{{e.type}}</div>
        </div>
        <div class="dropzone" x-drag-target x-model="elements.length" x-drop="onDrop(src, dest)"></div>

    </div>
    <div style="float:left; margin: 20px 0 0 10px;">
        <div x-ng-repeat="t in templates">
            <div class="draggable" x-draggable x-model="t">{{t.type}}</div>
        </div>
    </div>
    
</div>

CSS

body {
    color: #333;
    font: 82% Arial,Verdana,sans-serif;
    line-height: 20px;
}

.element {
    background-color: #eee;
    color: #333;
    padding: 3px;
    border: 1px solid #ddd;
}

.dropzone {
    height: 10px;
    border: 1px solid transparent;
}

.draggable:hover {
    cursor: pointer;
}
.drag-target {
    border: 1px dashed #f66;
}
.drag-hover {
    border: 1px dashed #3f3;
}

.animate-repeat.ng-move,
.animate-repeat.ng-enter,
.animate-repeat.ng-leave {
  -webkit-transition:all linear 0.5s;
  transition:all linear 0.5s;
}
 
.animate-repeat.ng-leave.ng-leave-active,
.animate-repeat.ng-move,
.animate-repeat.ng-enter {
  opacity:0;
  max-height:0;
}
 
.animate-repeat.ng-leave,
.animate-repeat.ng-move.ng-move-active,
.animate-repeat.ng-enter.ng-enter-active {
  opacity:1;
  max-height:30px;
}

JavaScript

jQuery.event.props.push('dataTransfer');

var app = angular.module('app', ['ngAnimate']);

function MainController($scope, $log) {
    $scope.elements = [];
    $scope.templates = [
        {type: "Drag Me 1"},
        {type: "Drag Me 2"},
        {type: "Drag Me 3"},
        {type: "Drag Me 4"}
    ];
    
    $scope.onDrop = function(src, dest){
        //dest should always be an index
        var destIndex = dest;
        var srcIndex = src.index;

        if(undefined !== srcIndex){
            // there's a src index, so we're moving the element
            var toMove = $scope.elements[srcIndex];
            if(srcIndex > destIndex){
                // if the src is higher than the dest, we should remove then add
                $scope.elements.splice(srcIndex, 1);
                $scope.elements.splice(destIndex, 0, toMove);
            } else {
                // if the dest is higher than the dest, we should add then remove
                $scope.elements.splice(destIndex, 0, toMove);
                $scope.elements.splice(srcIndex, 1);
            }
        } else {
            // assume it's a template that we're inserting
            $scope.elements.splice(dest, 0, {type: src.type });
        }
    }
}

app.factory('uuid', function() {
	"use strict";

	var _methods = {
		'random': function() {
			function _p8(s) {
				var p = (Math.random().toString(16)+"000000000").substr(2,8);
				return s ? "-" + p.substr(0,4) + "-" + p.substr(4,4) : p ;
			}
			return _p8() + _p8(true) + _p8(true) + _p8();
		},
		'empty': function() {
			return '00000000-0000-0000-0000-000000000000';
		}
	};
	return _methods;
});

app.factory('dragData', function() {
	"use strict";
    var cache = {};
	var _methods = {
		'register': function(key, data) {
			cache[key] = data;
		},
		'retrieve': function(key) {
			return cache[key];
		},
        'remove' : function(key) {
            var toReturn = cache[key];
            delete cache[key];
            return toReturn;
       ...