2

I have found out a beautiful solution on dragable tabs in angularjs from the following link Angular tabs - sortable/moveable

I implemented it in my page. But on refreshing the page it roll backs to previous state. So I planned to save or update the index value or reorder level of the tabs in database so that on refreshing the page I can arranged it properly. My question is how to get the changed value in ng-model or the array variable which is used in ng-repeat. I will provide my codes below

<uib-tabset justified="false" active="dashboardTab.active">
            <uib-tab sortable-tab index="$index" ng-repeat="tab in tabs| orderBy : 'order'" disable="tab.disabled" >
                <uib-tab-heading style="cursor:pointer">
                    <span>{{tab.Name}}</span>
                </uib-tab-heading>
            </uib-tab>
        </uib-tabset>
 <button class="btn btn-primary btn-sm" ng-click="saveTabs()" >Save Changes</button>

and the directive is

app.directive('sortableTab', function ($timeout, $document) {
return {
    link: function (scope, element, attrs, controller) {
        // Attempt to integrate with ngRepeat
        var match = attrs.ngRepeat.match(/^\s*([\s\S]+?)\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))?\s*$/);
        var tabs;
        scope.$watch(match[2], function (newTabs) {
            tabs = newTabs;
        });

        var index = scope.$index;
        scope.$watch('$index', function (newIndex) {
            index = newIndex;
        });

        attrs.$set('draggable', true);

        // Wrapped in $apply so Angular reacts to changes
        var wrappedListeners = {
            // On item being dragged
            dragstart: function (e) {
                console.log(e.originalEvent.dataTransfer);
                e.originalEvent.dataTransfer.effectAllowed = 'move';
                e.originalEvent.dataTransfer.dropEffect = 'move';
                e.originalEvent.dataTransfer.setData('application/json', index);
                element.addClass('dragging');
            },
            dragend: function (e) {
                //e.stopPropagation();
                element.removeClass('dragging');
            },

            // On item being dragged over / dropped onto
            dragenter: function (e) {
            },
            dragleave: function (e) {
                element.removeClass('hover');
            },
            drop: function (e) {
                e.preventDefault();
                e.stopPropagation();
                var sourceIndex = e.originalEvent.dataTransfer.getData('application/json');
                move(sourceIndex, index);
                element.removeClass('hover');
            }
        };

        // For performance purposes, do not
        // call $apply for these
        var unwrappedListeners = {
            dragover: function (e) {
                e.preventDefault();
                element.addClass('hover');
            },
            /* Use .hover instead of :hover. :hover doesn't play well with 
               moving DOM from under mouse when hovered */
            mouseenter: function () {
                element.addClass('hover');
            },
            mouseleave: function () {
                element.removeClass('hover');
            }
        };

        angular.forEach(wrappedListeners, function (listener, event) {
            element.on(event, wrap(listener));
        });

        angular.forEach(unwrappedListeners, function (listener, event) {
            element.on(event, listener);
        });

        function wrap(fn) {
            return function (e) {
                scope.$apply(function () {
                    fn(e);
                });
            };
        }

        function move(fromIndex, toIndex) {
            tabs.splice(toIndex, 0, tabs.splice(fromIndex, 1)[0]);
        };

    }
 }
});

On clicking save changes button, I want to get the changed value of tabindex in 'order' of tabs array. Any hope?

Nithin Mohan
  • 750
  • 16
  • 34

1 Answers1

0

This answer worked for me. In tab data add index value and display the tabs order by that index value. Then in move() function in directive add new index values as given below.

In controller add a function

app.controller('ctrlname', function ($scope) {
  $scope.data = [];
  $scope.data.tabs = [
   { title:'Dynamic Title 1', content:'Dynamic content 1', active:true, indexValue:1},
   { title:'Dynamic Title 2', content:'Dynamic content 2',indexValue: 2},
   { title:'Dynamic Title 3', content:'Dynamic content 3', indexValue: 3}
  ];
  $scope.saveDraggedTab = function(tabs){
     console.log(tabs);
     //do the logic here
  }
});

In directive add the following codes in move()

function move(fromIndex, toIndex) {
        tabs.splice(toIndex, 0, tabs.splice(fromIndex, 1)[0]);
        var counter = 1;
        angular.forEach(tabs, function (item, key) {
        item.indexValue = counter;
        counter++;
     });
     scope.saveDraggedTab(tabs);
 };
Nithin Mohan
  • 750
  • 16
  • 34