0

I've got a AngularJS directive that hooks up sortables.

I'm trying to create a directive that will allow me to drag and drop new items into a sortable. If that item is a 'section' it should allow further drag and drops into it recursively. The section inits a sortable itself and I attempt to connect the sortables. Problem is it never connects... I've built similar demos with jqueryUI alone so I know that its possible, my angular implementation is probably just messing something up. Any ideas?

sortable directive:

app.constant('sortableConfig', {
    connectWith: '.sortables'
});

app.directive('sortable', ['$timeout','sortableConfig', function ($timeout, sortableConfig) {
    return {
        restrict: 'AE',
        scope: {
            ngModel: '=',
            options: '='
        },
        link: function ($scope, $element, $attributes) {
            var ngModel = $scope.ngModel;

            var options = angular.extend(sortableConfig, 
                    $scope.$eval($attributes.options)),
                sortableIn = 0;

            console.log(ngModel)

            options.start = function(e, ui) {
                // Save position of dragged item
                ui.item.sortable = { index: ui.item.index() };
            };

            options.update = function(e, ui) {
                // For some reason the reference to ngModel in stop() is wrong
                ui.item.sortable.resort = ngModel;
            };

            options.receive = function(e, ui) {
                sortableIn = 1;
                ui.item.sortable.relocate = true;
                // added item to array into correct position and set up flag
                ngModel.splice(ui.item.index(), 0, ui.item.sortable.moved);
            };

            options.remove = function(e, ui) {
                // copy data into item
                if (ngModel.length === 1) {
                    ui.item.sortable.moved = ngModel.splice(0, 1)[0];
                } else {
                    ui.item.sortable.moved =  ngModel.splice(ui.item.sortable.index, 1)[0];
                }
            };

            options.over = function(e, ui) {
                sortableIn = 1;
            };

            options.out = function(e, ui) {
                sortableIn = 0;
            };

            options.beforeStop = function(e, ui) {
                // http://snipplr.com/view/49923/
                if (sortableIn == 0) { 
                    console.log('REMOVE!', ui.item.sortable.resort)
                    //ui.item.remove(); 
                    //ngModel.splice(ui.item.index(), 1);
                }
            };

            options.stop = function(e, ui) {
                // digest all prepared changes
                if (ui.item.sortable.resort && !ui.item.sortable.relocate) {
                    // Fetch saved and current position of dropped element
                    var end, start;
                    start = ui.item.sortable.index;
                    end = ui.item.index();

                    // Reorder array and apply change to scope
                    ui.item.sortable.resort.splice(
                        end, 0, ui.item.sortable.resort.splice(start, 1)[0]);
                }
            };

            $timeout(function(){
                console.log(options)
                $element.sortable(options);
            })
        }
    }
}]);

sortable template:

 <ul sortable class="sortable" ng-model="ngModel">
<li class="pull-left" ng-repeat="item in ngModel" ng-model="item" ng-style="drawLayout(item)">
    <div ng-if="isField(item)"
         class="btn btn-info btn-draggable layout-field"
         ng-click="showDetails(item)">{{item.name}}</div>

    <div droppable 
         ng-model="item.children"
         dropped="layoutDropped(dragModel, dropModel)" 
         ng-if="item.typeOf == 'section'"
         class="panel panel-default layout-section">

        <div class="panel-heading" ng-click="showDetails(item)">
            {{item.name}}
            <div ng-show="item.helpTextOpt != 'none'">
                <hr />
                <p>{{item.helpText}}</p>
            </div>
        </div>
        <div class="panel-body" onload="ngModel=item.children"
             ng-include="'views/app-builder/layout.html'">
        </div>
    </div>
</li>
3
  • suggest using nested sortable plugin which is an extension of jQuery UI sortable. A demo in plunker or jsfiddle.net would help Commented Nov 17, 2013 at 17:28
  • Ya, found a few ... any you would recommend? Commented Nov 17, 2013 at 17:46
  • only know of one...never had problems with it, haven't used for long time Commented Nov 17, 2013 at 17:52

2 Answers 2

2

You could reference the code of Angular-NestedSortable(https://github.com/JimLiu/Angular-NestedSortable). An Angularjs ui component that can sort nested lists and bind data, and it dosen't need to depend on jQuery.

Sign up to request clarification or add additional context in comments.

Comments

0

I was able to come up with a solution that uses jQueryUI's sortable and can hook into draggable and droppable. Full details here

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.