Drag and Drop
by dunerunner
HTML
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.no-icons.min.css">
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css">
<script src="http://cdnjs.cloudflare.com/ajax/libs/hammer.js/1.0.5/hammer.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
<script src="http://s.cdpn.io/61329/angular-hammer.js"></script>
<script src="http://s.cdpn.io/61329/zest.js"></script>
<div class="container" ng-app="dragndropdemo">
<div class="row" ng-controller="dragndropdemo">
<ul id="names" class="span-3">
<li class="input-wrap transition" cu-repeat-reorder='name in names' cu-reorder-handle="i.icon-reorder">
<i class="icon-reorder"></i>
<span class="player" type='text'
tabindex='{{$index + 1}}'
ng-class="{'last-player': $index == names.length-1}">{{name.val}}</span>
</li>
<!--<div class="input-wrap">
<input class="temp-player" type='text'
ng-model='tempplayer'
ng-change='updateNames()'
tabindex='{{names.length + 1}}'
placeholder='Enter a name...'/>
</div>-->
</ul>
{{names}},{{tempplayer}}
</div>
</div>
CSS
ul {
list-style-type:none;
}
$player-input-border: 1px solid #ccc
.span-3
width: 277px
.input-wrap-header
border: $player-input-border
border-top-radius: 4px
border-bottom-radius: 0
width: 208px !important
.input-wrap, .input-wrap-header
float: left
clear: left
width: 240px
.input-wrap
i.icon-reorder //to provide a bigger target we pad then reverse with -ve margins
padding: 6px
margin: -6px
margin-left: -26px
margin-top: -5px
color: #757575
input
margin-bottom: 0
border-radius: 0
border: $player-input-border
border-top: none
padding-right: 20px
&:first-child input
border-top: $player-input-border
border-top-radius: 4px
&:last-child input
border-bottom-radius: 4px
&.dragging input
border: $player-input-border
&.dragging-after input
background-color: green
border-top: $player-input-border
&.dragging-before input
background-color: red
[cu-reorder-handle]
z-index: 10
position: relative
.dragging[cu-reorder-handle]
z-index: 11
.active-drag-below
-moz-user-select: none
-khtml-user-select: none
-webkit-user-select: none
user-select: none
JavaScript
/*
A LOT of this code comes from the angular.js project
additionally this uses zest for dom selection and hammer.js (with an angular-hammer wrapper) for touch and mouse-drag event support
*/
'use strict';
var HashQueueMap, dragndropdemo, hashKey, isArray, module, nextUid, uid;
module = angular.module('dragndropdemo', ['hmTouchEvents']);
dragndropdemo = (function () {
function dragndropdemo($scope, $timeout) {
$scope.names = [{
val: 'bob'
}, {
val: 'lucy'
}, {
val: 'john'
}, {
val: 'luke'
}, {
val: 'han'
}];
}
return dragndropdemo;
})();
this.dragndropdemo = dragndropdemo;
module.directive('cuReorderHandle', function () {
return {
transclude: false,
priority: 999,
terminal: false,
compile: function (element, attr, linker) {
var dragElement;
dragElement = angular.element(zest(attr.cuReorderHandle, element[0])[0]);
if (dragElement != null) {
dragElement.attr("hm-drag", "reorderFuncs.moveevent($event, $elementRef, $index)");
dragElement.attr("hm-dragstart", "reorderFuncs.startevent($event, $elementRef, $index)");
return dragElement.attr("hm-dragend", "reorderFuncs.stopevent($event, $elementRef, $index)");
}
}
};
});
module.directive('cuRepeatReorder', function () {
return {
transclude: "element",
priority: 1000,
terminal: true,
compile: function (element, attr, linker) {
return function (scope, iterStartElement, attr) {
var expression, keyIdent, lastOrder, lhs, match, ngRepeatWatch, reorderFuncs, rhs, valueIdent;
expression = attr.cuRepeatReorder;
match = expression.match(/^\s*(.+)\s+in\s+(.*)\s*$/);
lhs = void 0;
rhs = void 0;
valueIdent = void 0;
...