From 30c7327087d64c16eae21fb50729bfe219ecb354 Mon Sep 17 00:00:00 2001 From: "marcel.juenemann" Date: Sun, 6 Apr 2014 00:37:53 +0200 Subject: [PATCH] Initial code, first steps towards demo --- .gitignore | 2 + angular-drag-and-drop-lists.js | 155 +++++++++++++++++++++++++++++++++ demo/demo-framework.js | 8 ++ demo/index.html | 55 ++++++++++++ demo/simple/simple.html | 2 + demo/simple/simple.js | 3 + package.json | 13 +++ 7 files changed, 238 insertions(+) create mode 100644 .gitignore create mode 100644 angular-drag-and-drop-lists.js create mode 100644 demo/demo-framework.js create mode 100644 demo/index.html create mode 100644 demo/simple/simple.html create mode 100644 demo/simple/simple.js create mode 100644 package.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7a1537b --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.idea +node_modules diff --git a/angular-drag-and-drop-lists.js b/angular-drag-and-drop-lists.js new file mode 100644 index 0000000..382ed5c --- /dev/null +++ b/angular-drag-and-drop-lists.js @@ -0,0 +1,155 @@ +'use strict'; + +/* Controllers */ +angular.module('myApp.controllers', []) + .directive('dndDraggable', function($parse, $timeout) { + return function(scope, element, attr) { + var model = attr.dndDraggable; + + element.attr("draggable", "true"); + + element.on('click', function(event) { + scope.$apply(function() { + $parse(attr.dndSelected)(scope); + }); + + event.stopPropagation(); + }); + + element.on('dragstart', function(event) { + var data = angular.toJson(scope.$eval(model)); + event.dataTransfer.setData("json", data); + event.dataTransfer.effectAllowed = attr.dndEffectAllowed; + + // We can not hide the element instantly because + // that would abort the dragging + element.addClass("dndDragging"); + $timeout(function() { + element.addClass("dndDraggingSource"); + }, 0); + + event.stopPropagation(); + }); + + element.on('dragend', function(event) { + scope.$apply(function() { + switch (event.dataTransfer.dropEffect) { + case "move": + $parse(attr.dndMoved)(scope); + break; + + case "copy": + $parse(attr.dndCopied)(scope); + break; + } + }); + + element.removeClass("dndDragging"); + element.removeClass("dndDraggingSource"); + event.stopPropagation(); + }); + + }; + }) + + .directive('dndDropzone', function($timeout) { + return function(scope, element, attr) { + var listNode = element[0]; + var placeholder = angular.element("
  • "); + var placeholderNode = placeholder[0]; + var dropzoneList = attr.dndDropzone; + + element.on('dragover', function(event) { + // convert type list to real array + if (Array.prototype.indexOf.call(event.dataTransfer.types, "json") === -1) { + return true; + } + + if (event.target.parentNode === listNode) { + // This would be easier with index() and before() methods + var targetIndex = Array.prototype.indexOf.call(listNode.children, event.target); + var placeholderIndex = Array.prototype.indexOf.call(listNode.children, placeholderNode); + var insertBefore = targetIndex < placeholderIndex ? event.target : event.target.nextSibling; + listNode.insertBefore(placeholderNode, insertBefore); + } + + element.addClass("dragover"); + event.preventDefault(); + event.stopPropagation(); + }); + + element.on('dragenter', function(event) { + // Add placeholder element if it's not shown yet + // This is especially needed with empty lists + if (placeholderNode.parentNode != listNode) { + element.append(placeholder); + } + + event.stopPropagation(); + + }); + + element.on('dragleave', function(event) { + element.removeClass("dragover"); + $timeout(function() { + // If we are still inside the dropzone the dragover + // class will have been set again in the meantime + if (!element.hasClass("dragover")) { + placeholder.remove(); + } + }, 100); + }); + + element.on('drop', function(event) { + var placeholderIndex = Array.prototype.indexOf.call(listNode.children, placeholderNode); + + var target = scope.$eval(dropzoneList); + var model = JSON.parse(event.dataTransfer.getData("json")); + + + scope.$apply(function() { + target.splice(placeholderIndex, 0, model); + }); + + placeholder.remove(); + + event.preventDefault(); + event.stopPropagation(); + + }); + }; + }) + + .controller('MyCtrl1', ['$scope', function($scope) { + $scope.toolbox = [ + { + type: "item", + id: 1 + }, + { + type: "container", + id: 1, + columns: [[], []] + } + ]; + + $scope.lists = [[], []]; + + $scope.model = { + selected: null + }; + + $scope.selectItem = function(item) { + console.log("select reached me!"); + $scope.model.selected = item; + }; + + $scope.$watch('lists', function(lists) { + $scope.result = angular.toJson(lists, true); + }, true); + + + }]) + .controller('MyCtrl2', [function() { + + }]); diff --git a/demo/demo-framework.js b/demo/demo-framework.js new file mode 100644 index 0000000..86cef2e --- /dev/null +++ b/demo/demo-framework.js @@ -0,0 +1,8 @@ +angular.module("demo", ["ngRoute"]).config(function($routeProvider) { + $routeProvider + .when('/simple', { + templateUrl: 'simple/simple.html', + controller: 'SimpleDemoController' + }) + .otherwise({redirectTo: '/simple'}); +}); diff --git a/demo/index.html b/demo/index.html new file mode 100644 index 0000000..5570551 --- /dev/null +++ b/demo/index.html @@ -0,0 +1,55 @@ + + + + + Drag & Drop Lists for angular.js + + + + + + + + + + + + + + + + + + + +
    + + + +
    + +
    + + + + \ No newline at end of file diff --git a/demo/simple/simple.html b/demo/simple/simple.html new file mode 100644 index 0000000..ea2fd5c --- /dev/null +++ b/demo/simple/simple.html @@ -0,0 +1,2 @@ +Hello World! + diff --git a/demo/simple/simple.js b/demo/simple/simple.js new file mode 100644 index 0000000..5356fc9 --- /dev/null +++ b/demo/simple/simple.js @@ -0,0 +1,3 @@ +angular.module("demo").controller("SimpleDemoController", function($scope) { + +}); diff --git a/package.json b/package.json new file mode 100644 index 0000000..a48c5cc --- /dev/null +++ b/package.json @@ -0,0 +1,13 @@ +{ + "name": "angular-drag-and-drop-lists", + "version": "1.0.0", + "description": "Angular directives for sorting nested lists using the HTML5 Drag and Drop API", + "repository": "https://github.com/marceljuenemann/angular-drag-and-drop-lists", + "license": "MIT", + "devDependencies": { + "http-server": "^0.6.1" + }, + "scripts": { + "start": "http-server -p 8000" + } +}