JSFiddle - React, Tailwind, and code Playground

by dmarko484

HTML

<script src="http://code.angularjs.org/angular-0.10.6.min.js"
ng:autobind></script>

<div ng:app ng:controller="controller">
    <div my:sortable="list">
        <div ng:repeat="item in list" class="item">{{item}}</div>
    </div>
    <hr />
    <div ng:repeat="item in list">{{item}}</div>
</div>

CSS

.item, .placeholder {
    padding: 2px;
    width: 150px;
    height: 30px;
    border: 1px solid #333;
    background: #EEE;
    margin: 3px;
}

.placeholder {
    background: #AEF;
}

JavaScript

angular.directive("my:sortable", function(expression, compiledElement){
    // add my:sortable-index to children so we know the index in the model
    compiledElement.children().attr("my:sortable-index","{{$index}}");
    
    return function(linkElement){
        var scope = this;             
        
        linkElement.sortable({
            placeholder: "placeholder",
            opacity: 0.8,
            axis: "y",
            update: function(event, ui) {
                // get model
                var model = scope.$apply(expression);
                // remember its length
                var modelLength = model.length;
                // rember html nodes
                var items = [];

                // loop through items in new order
                linkElement.children().each(function(index) {
                    var item = $(this);
                    
                    // get old item index
                    var oldIndex = parseInt(item.attr("my:sortable-index"), 10);
                    
                    // add item to the end of model
                    model.push(model[oldIndex]);

                    if(item.attr("my:sortable-index")) {
                        // items in original order to restore dom
                        items[oldIndex] = item;
                        // and remove item from dom
                        item.detach();
                    }
                });
                
                model.splice(0, modelLength);

                // restore original dom order, so angular does not get confused
                linkElement.append.apply(linkElement,items);

                // notify angular of the change
                scope.$digest();
            }
        });
    };
});

var controller = function () {
    this.list = ["one1", "two", "three", "four", "five", "six"];
};