sheercms
Version:
Sheer Cliff CMS is a simple and powerful content management system (CMS) for Node JS.
209 lines (188 loc) • 8.57 kB
JavaScript
app.directive('sortableSelect', function ($parse) {
return {
restrict: 'EC',
scope: {
list: '=list',
textprop: '',
idprop: '',
selected: '=selected'
},
template: '<div class="sortable-multiselect">' +
'<div class="list-source"><div ng-repeat="item in items | filter: {selected: false}" ng-click="clickItem(item, $index)" ng-dblclick="dblclickItem(item, $index)" ng-class="{active: item == itemActive}">{{item.text}}</div></div>' +
'<div class="list-move-buttons">' +
' <a href="javascript:void(0);" ng-click="select()" ng-class="{disabled: itemActive == null}"><i class="fa fa-arrow-right"></i></a>' +
' <a href="javascript:void(0);" ng-click="deselect()" ng-class="{disabled: selectionActive == null}"><i class="fa fa-arrow-left"></i></a></div>' +
'<div class="list-selected"><div ng-repeat="item in selected" ng-click="clickSelected(item, $index)" ng-dblclick="dblclickSelected(item, $index)" ng-class="{active: item == selectionActive}">{{item[textprop]}}</div></div>' +
'<div class="list-sort-buttons">' +
' <a href="javascript:void(0);" ng-click="moveUp()" ng-class="{disabled: canMoveUp == false}"><i class="fa fa-arrow-up"></i></a>' +
' <a href="javascript:void(0);" ng-click="moveDown()" ng-class="{disabled: canMoveDown == false}"><i class="fa fa-arrow-down"></i></a></div>' +
'</div>',
link: function ($scope, element, attrs) {
$scope.items = [];
$scope.itemActive = null;
$scope.selectionActive = null;
$scope.canMoveUp = false;
$scope.canMoveDown = false;
$scope.$watch(function(scope) {
return scope.selected;
},
function() {
if ($scope.selected) {
//make sure the correct items are marked as selected
mergeSelected();
}
else if ($scope.items) {
//deselect all items
for(var i = 0; i < $scope.items.length; i++)
$scope.items[i].selected = false;
}
}
);
$scope.clickItem = function(item, index) {
if (item == $scope.itemActive)
$scope.itemActive = null;
else
$scope.itemActive = item;
};
$scope.dblclickItem = function(item, index) {
$scope.select(item);
};
$scope.clickSelected = function(item, index) {
if (item == $scope.selectionActive) {
$scope.selectionActive = null;
$scope.canMoveUp = false;
$scope.canMoveDown = false;
}
else {
$scope.selectionActive = item;
$scope.canMoveUp = (index > 0);
$scope.canMoveDown = (index < $scope.selected.length - 1);
}
};
$scope.dblclickSelected = function(item, index) {
$scope.deselect(item);
};
/* right arrow */
$scope.select = function(item) {
if (!item)
item = $scope.itemActive;
if (item) {
item.selected = true;
$scope.selectionActive = null;
$scope.selected.push(item.ref);
}
};
/* left arrow */
$scope.deselect = function(item) {
if (!item)
item = $scope.selectionActive;
if (item) {
//find the item in our source list and mark it as not selected anymore
for(var i = 0; i < $scope.items.length; i++) {
var a = $scope.items[i];
if (a.ref == item) {
a.selected = false;
break;
}
}
//find the item in the selected list and remove it
for(var i = 0; i < $scope.selected.length; i++) {
var a = $scope.selected[i];
if (a == item) {
$scope.selected.splice(i, 1);
break;
}
}
}
};
$scope.moveUp = function() {
if ($scope.selected && $scope.selected.length > 1) {
//get the index of the selected item
var index = -1;
for (var i = 0; i < $scope.selected.length; i++) {
var a = $scope.selected[i];
if (a == $scope.selectionActive) {
index = i;
break;
}
}
if (index > 0) { //can't move up the first item
//swap with the next item in the list
swap(index, index - 1);
if (index - 1 == 0)
$scope.canMoveUp = false;
if (index - 1 < $scope.selected.length - 1)
$scope.canMoveDown = true;
}
}
};
$scope.moveDown = function() {
if ($scope.selected && $scope.selected.length > 1) {
//get the index of the selected item
var index = -1;
for (var i = 0; i < $scope.selected.length; i++) {
var a = $scope.selected[i];
if (a == $scope.selectionActive) {
index = i;
break;
}
}
if (index < $scope.selected.length - 1) { //can't move down the last item
//swap with the next item in the list
swap(index, index + 1);
if (index + 1 == $scope.selected.length - 1)
$scope.canMoveDown = false;
if (index + 1 > 0)
$scope.canMoveUp = true;
}
}
};
function swap(index1, index2) {
if (index1 >= 0 && index2 >= 0 &&
index1 < $scope.selected.length &&
index2 < $scope.selected.length &&
index1 != index2) {
var temp = $scope.selected[index1];
$scope.selected[index1] = $scope.selected[index2];
$scope.selected[index2] = temp;
}
}
function mergeSelected() {
if ($scope.items && $scope.selected) {
var idprop = $scope.idprop || 'id';
for (var i = 0; i < $scope.items.length; i++) {
var item = $scope.items[i];
var selected = false;
for (var j = 0; j < $scope.selected.length; j++) {
var b = $scope.selected[j];
if (b == item.ref || item._id == b[idprop]) {
selected = true;
break;
}
}
item.selected = selected;
}
}
}
function init() {
if ($scope.list) {
var idprop = $scope.idprop || 'id';
for(var i = 0; i < $scope.list.length; i++) {
var a = $scope.list[i];
var obj = {
_id: a[idprop],
text: a[$scope.textprop],
active: false,
selected: false,
index: i,
ref: a
};
$scope.items.push(obj);
}
mergeSelected();
}
}
init();
}
};
});