0

I'm trying to have sortable panels on each of my tab. If I put panels on index.html it works, but when used inside directive templateUrl: tabs.html it doesn't. Please see the Plunker example here

My html file:

<body>
  <div class="container" ng-controller="testCtrl">
    <app-tabs></app-tabs>
  </div>

  <script>
        $(document).ready(function () {
        $(function () {
            $(".sortable").sortable();
        });
    });
  </script>
</body>

My tabs.html file:

<ul class="nav nav-pills">
    <li role="presentation" ng-class="{ active:isSet(t.Id) }" ng-repeat=" t in myListOfTabs">
        <a href ng-click="setTab(t.Id)">{{t.Name}}</a>
    </li>
    <li role="presentation" ng-class="{ active:isSet(1) }">
    <a href ng-click="setTab(1)">Add Tab</a>
    </li>
</ul>

<div ng-repeat=" t in myListOfTabs" ng-show="isSet(t.Id)">
    <div class="row sortable">
      <div class="panel panel-default">
        <div class="panel-body">Panel 1</div>
      </div>
      <div class="panel panel-default">
        <div class="panel-body">Panel 2</div>
      </div>
      <div class="panel panel-default">
        <div class="panel-body">Panel 3</div>
      </div>
      <div class="panel panel-default">
        <div class="panel-body">Panel 4</div>
      </div>
      <div class="panel panel-default">
        <div class="panel-body">Panel 5</div>
      </div>
      <div class="panel panel-default">
        <div class="panel-body">Panel 6</div>
      </div>
    </div>
</div>

My app.js file:

(function() {

  var modelTabs = [{
    Id: 2,
    Name: "Tab 1",
    Layout: 1
  }, {
    Id: 3,
    Name: "Tab 2",
    Layout: 1
  }, {
    Id: 4,
    Name: "Tab 3",
    Layout: 1
  }];


  var app = angular.module('appTest', []);


  app.controller('testCtrl', ["$scope", function($scope) {

    $scope.myListOfTabs = modelTabs;
  }]);


  app.directive("appTabs", function() {
    return {
      restrict: "E",
      templateUrl: "tabs.html",
      controller: function($scope) {
        $scope.tab = 2;

        $scope.isSet = function(checkTab) {
          return $scope.tab === checkTab;
        };

        $scope.setTab = function(activeTab) {
          $scope.tab = activeTab;
        };
      },
      controllerAs: "tab"
    };
  });

})();
Whistler
  • 1,897
  • 4
  • 29
  • 50

2 Answers2

1

First of all you'll need to select the .sortable elements and apply the sortable plugin to them. Next issue is that the items inside that ng-repeat won't exist in the DOM at the time link runs for the parent directive. You can find a clear explanation of this here. For now the only solution is a timeout.

setTimeout(function() {
    $('.sortable', element).sortable();
}, 100);

Also <div ng-repeat=" t in myListOfTabs" ng-show="isSet(t.Id)" class="row sortable"> so that the .sortable class is not inside another <div>.

Here is the working plunker.

Community
  • 1
  • 1
Sergiu Paraschiv
  • 9,929
  • 5
  • 36
  • 47
0

All you need to do is create a sortable directive

app.directive("sortable", function() {
    return {
      restrict: "C",
      link: function(scope, element, attrs) {
        element.sortable();
      }
    }
});

This assures that once the element exists, the plugin will be bound to it

DEMO

charlietfl
  • 170,828
  • 13
  • 121
  • 150
  • Helpful Solution. Can you please have a look at https://stackoverflow.com/questions/50109588/how-can-i-pass-an-angularjs-object-through-jquery-sortable?noredirect=1#comment87236942_50109588 – Shashishekhar Hasabnis May 01 '18 at 04:18