Angular Sortable Table

by TheFiddler

HTML

<div ng-app="sortableApp" ng-controller="sortableController" class="container">


  <div>
    <div>
      <div ui-sortable="sortableOptions" class="apps-container screen" ng-model="modelA" app-column="a">
        <div id="{{app.id}}" class="app" ng-repeat="app in modelA">{{app.id}} {{app.name}}</div>
      </div>
    </div>
      <!-- Final -->
    <div>
      <div ui-sortable="sortableOptions" class="apps-container screen" ng-model="modelB" app-column="b">
        <div id="{{app.id}}" class="app" ng-repeat="app in modelB">{{app.id}} {{app.name}}</div>
      </div>
    </div>
    <div style="clear: both;"></div>
</div>

  <div>
    <button type="button" ng-click="logModels()">Log Models</button>
    <ul class="list logList">
      <li ng-repeat="entry in sortingLog" class="logItem">
        {{entry}}
      </li>
    </ul>
  </div>
  
  <div class="clear"></div>

  <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
  <script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.8/angular.min.js"></script>
  <script src="https://rawgithub.com/angular-ui/ui-sortable/master/src/sortable.js"></script>
</div>

CSS

.list {
	list-style: none outside none;
	margin: 10px 0 30px;
}

.apps-container {
  border: 2px dashed blue;
  margin: 10px 10px 0 0;
  padding: 5px;
}

.app {
    height:1.8em;
	padding: 5px 10px;
	margin: 5px 0;
	border: 2px solid #444;
	border-radius: 5px;
	background-color: #e4e4e4;

	font-size: 1em;
	cursor: move;
}

.app-ph {
	height:1.8em;
	padding: 5px 10px;
	margin: 5px 0;
	border: 2px solid #444;
	border-radius: 5px;
	background-color: #333;

	font-size: 1em;
	cursor: move;
}


/***  Extra ***/

body {
	font-family: Verdana, 'Trebuchet ms', Tahoma;
}

.logList {
	margin-top: 20px;
	width: 250px;
	min-height: 300px;
	padding: 5px 15px;
	border: 5px solid #000;
	border-radius: 15px;
}

.logItem {
  margin-bottom: 10px;
}

.logList:before {
	content: 'log';
	padding: 0 5px;
	position: relative;
	top: -1.1em;
	background-color: #FFF;
}

.container {
	width: 750px;
	margin: auto;
}

h2 {
	text-align: center;
}

.floatleft {
  float: left;
}

.floatright {
  float: right;
}

.clear {
  clear: both;
}

JavaScript

function findAppById(appList, id){

    var app=$.grep(appList, function(e){return e.id == id})[0]
    if(app && app !== undefined)
        return app;
    else
        return null;
}

var myapp = angular.module('sortableApp', ['ui.sortable']);

myapp.controller('sortableController', function ($scope, $filter) {
  var tmpList = [];
  
  $scope.rawScreens =
    [{
      id:'01',
      name: 'James Robert',
      university: 'Ohio State University',
      table: "1"
    },{
      id:'02',
      name: 'George Michael',
      university: 'Harvard Law School',
      table: "1"
    },{
      id:'03',
      name: 'Penelope Cruise',
      university: 'George Washington University',
      table: "2"
    },];
  
  $scope.modelA = $filter('filter')($scope.rawScreens, {table:'1'});
  $scope.modelB = $filter('filter')($scope.rawScreens, {table:'2'});
  
  $scope.sortingLog = [];
  
  $scope.sortableOptions = {
    placeholder: "app-ph",
    connectWith: ".apps-container",
    start: function(event, ui){
      
    },
    beforeStop: function(event, ui){
      // on drop change the category if needed
      var movedApp = findAppById($scope.rawScreens, ui.helper[0].id);
      if (movedApp) {
        var newColumn = ui.helper.parent()[0].getAttribute('app-column');
        if (movedApp.column !== newColumn) {
         movedApp.column = newColumn; 
        }
      }
    },
  };
  
  $scope.logModels = function () {
    $scope.sortingLog = [];
    var screenCategories = [$scope.modelA, $scope.modelB];
    for (var i = 0; i < screenCategories.length; i++) {
      var logEntry = screenCategories[i].map(function (x) {
        return x.name;
      }).join(', ');
      logEntry = 'container ' + (i+1) + ': ' + logEntry;
      $scope.sortingLog.push(logEntry);
    }
  };
});