<!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