JSFiddle - React, Tailwind, and code Playground

by chrisloughnane

HTML

<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.25/angular.js"></script>
<div ng-app="myApp" ng-controller="myController">
    <script type="text/ng-template"  id="tree_item_renderer.html">
    <div class="child-draggable-field" my-drag-drop="childDraggableItemsOption">
    		<div ng-repeat="data in data.children" ng-class="{'element-class': data.level > 1}">
   			 	<div class="element"> {{data.name}} ------ {{$parent.$parent.data.children.length}}</div>
          <div ng-include="'tree_item_renderer.html'">
              </div>
    			</div>
    </div>
</script>
    <div class="draggable-field" my-drag-drop="draggableItemsOption">
        <div ng-repeat="data in fields">
            <div class="element" ng-class="{'element-class': data.level > 1}"> 
              {{data.name}}
              <div ng-include="'tree_item_renderer.html'">
              </div>
           </div>
   			</div>
    </div>
</div>

CSS

.element {
   border: 1px solid #333;
   padding: 10px 10px;
   position: relative;
}

.element-class {
  margin-left: 20px;
}

.moverBtn {
  position: absolute;
  top: 2px;
  right: 10px;
}

JavaScript

angular.module("myApp", []).
controller("myController", ['$scope', function($scope) {
    $scope.fields = [{
    		"name": "parent1",
        "level": 1,
        "children": [{
         		"name": "child1",
            "level": 2
        }, {
        		"name": "child2",
            "level": 2
        }, {
        		"name": "child3",
            "level": 2,
            "children": [{
            		"name": "grandChild1",
                "level": 3
            }, {
            		"name": "grandChild2",
                "level": 3
            }]
        }]
    }, {
    		"name": "parent2",
        "level": 1,
        "children": [{
        	"name": "child4",
          "level":2
        }]
    }, {
    		"name": "parent3",
        "level": 1
    }];
    
    $scope.draggableItemsOption = {
    	"moverElement": ".moverBtn",
			"containment": ".draggable-field"
    }
    
    $scope.childDraggableItemsOption = {
    		"containment": "parent"
    }
}]).directive("myDragDrop", ['$timeout', function ($timeout) {

		return {
			restrict:'A',
			scope: {
				myDragDrop:"="
			},
			link: function ($scope, element, attrs) {
				debugger;
				var options = $scope.myDragDrop;
				var $container = element;
			
				
				var sortableOptions = {
        	 /* handle: options.moverElement, */
           containment: options.containment,
           delay: 0,
           sort: dragInProgress
				 };
				debugger;

				if($container.sortable){
					$container.sortable(sortableOptions);
				}
				
        function dragInProgress(event,ui) {
        debugger;
						var container = $container;
					  var placeholder = container.children('.ui-sortable-placeholder');
					  var draggedCenterX = ui.helper.position().left + ui.helper.outerWidth()/2;
					  var draggedCenterY = ui.helper.position().top + ui.helper.outerHeight()/2;

					    $.each(container.children(), function(){
					    	var item = $(this);

					        if(!item.hasClass('ui-sortable-helper') &&...