<!DOCTYPE html>
<html ng-app="drag">
<head>
<meta charset="utf-8" />
<title>Handsontable in resizable div with angular</title>
<link rel="stylesheet" href="//code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css">
<link rel="stylesheet" href="style.css" />
<script data-require="jquery" data-semver="2.0.3" src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
<script data-require="jqueryui" data-semver="1.10.0" src="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.10.0/jquery-ui.js"></script>
<script data-require="angular.js@*" data-semver="1.2.6" src="http://code.angularjs.org/1.2.6/angular.js"></script>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/jquery-handsontable/0.10.2/jquery.handsontable.css" />
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery-handsontable/0.10.2/jquery.handsontable.full.js"></script>
<script src="script.js"></script>
</head>
<body>
Use the plus + signs to drag the elements
v{{version}}
<div ng-controller="dragController">
<div id="outer">
<div id="inner">
<div ht="0" resizable id="div{{elem.name}}" ng-repeat="elem in elements" style="top: {{elem.top || 0}}px; left: {{elem.left || 0}}px" class="greenBox">
<div class="handle" draggable="">+</div>
<div>element #{{elem.name}}</div>
<div>{{elem.top}}</div>
<div>{{elem.left}}</div>
</div>
</div>
</div>
Events ({{events.length}})
<div ng-repeat="event in events">
<div>{{event | json}}</div>
</div>
</div>
</body>
</html>
#outer
/*display block*/
padding 0px
.handle
display: block;
width 10px
margin 0px 5px 5px 0px
background-color #FE4
.greenBox
position absolute
background-color #CE6
width 100px
border 1px solid black
padding 10px
#inner
position relative
margin 50px
width 80%
height 500px
background-color #888
overflow scroll
This shows how to databind position of draggable elements. Also illustrates use
of a "drag handle" that is the only allowed way to drag the object. Also
demonstrates constraint of draggable elements to their parent container.
console.log('this is from coffeescript file');
module = angular.module("drag", [])
module.controller("dragController", ["$scope", ($scope) ->
$scope.grid = 20
$scope.version = 169
$scope.data = [
["", "Madserati", "Mazda", "Mercedes", "Mini", "Mitsubishi"],
["2009", 0, 2941, 4303, 354, 5814],
["2010", 5, 2905, 2867, 412, 5284],
["2011", 4, 2517, 4822, 552, 6127],
["2012", 2, 2422, 5399, 776, 4151]
];
#angular.element("#example").handsontable(
#data: data
#minSpareRows: 1
#colHeaders: true
#contextMenu: true
#)
$scope.events = []
$scope.elements = []
$scope.elements.push(top: 27, left: 57, name: "0")
$scope.elements.push(top: 135, left: 40, name: "1")
$scope.elements.push(top: 184, left: 227, name: "2")
])
module.factory "debounce", ($timeout, $q) ->
(func, wait, immediate) ->
timeout = undefined
deferred = $q.defer()
->
context = this
args = arguments
later = ->
timeout = null
unless immediate
deferred.resolve func.apply(context, args)
deferred = $q.defer()
callNow = immediate and not timeout
$timeout.cancel timeout if timeout
timeout = $timeout(later, wait)
if callNow
deferred.resolve func.apply(context, args)
deferred = $q.defer()
deferred.promise
module.directive("ht", [ ->
restrict: "A"
link: (scope, element, attrs) ->
if +attrs.ht == scope.$index
$.handsontable?(
data: scope.data
minSpareRows: 1
colHeaders: true
contextMenu: true
)
])
module.directive("resizable", [ "debounce", (debounce) ->
restrict: "A"
link: (scope, element, attrs) ->
broadcastResize = undefined
dbResize = undefined
broadcastResize = (event, ui) ->
if attrs.resizable?
# make sure size matches grid
ui.size.width -= ui.size.width % +attrs.resizable
ui.size.height -= ui.size.height % +attrs.resizable
console.log "broadcasting resize: " + (JSON.stringify(ui.size))
scope.$root.$broadcast "resize", ui.element.parents(".widget"), ui.size
dbResize = debounce(broadcastResize, 800, false)
minHeight = 1
minWidth = 1
element.resizable
grid: 20
ghost: true
helper: "ui-resizable-helper"
start: (event, ui) ->
#console.log "start resize"
minHeight = /\d+/.exec(attrs.$$element.css("min-height") )[0] or 1
minWidth = /\d+/.exec(attrs.$$element.css("min-width") )[0] or 1
stop: (event, ui) ->
dbResize event, ui
resize: (event, ui) ->
if (ui.size.width < minWidth or ui.size.height < minHeight)
event.preventDefault()
])
module.directive "draggable", ($document) ->
(scope, element, attr) ->
[x, y, container, startX, startY] = [null, null, null, null, null]
# Prevent default dragging of selected content
mousemove = (event) ->
y = event.pageY - startY
x = event.pageX - startX
#console.log "x: " + x + " y: " + y
if x < 0 then x = 0
if y < 0 then y = 0
x = scope.grid * Math.floor(x/scope.grid)
y = scope.grid * Math.floor(y/scope.grid)
scope.$apply( ->
scope.$parent.events.push mousemove: x: x, y: y, pageX: event.pageX, pageY: event.pageY, startY: startY, startX: startX
)
#console.log "#{event.pageX} #{event.pageY} "
container.css
top: y + "px"
left: x + "px"
mouseup = ->
$document.unbind "mousemove", mousemove
$document.unbind "mouseup", mouseup
#debugger
scope.elem.top = y
scope.elem.left = x
console.log element
scope.$apply( ->
scope.$parent.events.push mouseup: x: x, y: y
)
startX = 0
startY = 0
x = scope.elem.left
y = scope.elem.top
container = null
element.css
cursor: "pointer"
element.on "mousedown", (event) ->
return unless event.which == 1
event.preventDefault()
console.log 'mousedown'
console.log event
console.log element
container = attr.$$element.parent()
console.log container
scope.$apply( ->
scope.$parent.events = ["mousedown": x: x, y: y, pageX: event.pageX, pageY: event.pageY, startY: startY, startX: startX]
)
startX = event.pageX - x
startY = event.pageY - y
$document.on "mousemove", mousemove
$document.on "mouseup", mouseup