var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope, $filter) {
$scope.name = 'World';
$scope.availableItemsLeft = [];
$scope.availableItemsRight = [];
for (var i = 0; i < 25; i++) {
$scope.availableItemsLeft.push({ name: 'name' + i, id: 'id' + i });
//$scope.availableItemsRight.push({ name: 'name0' + i, id: 'id0' + i });
}
});
app.filter('startFrom', function() {
return function(input, start) {
start = +start;
return input.slice(start);
};
});
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>
document.write('<base href="' + document.location + '" />');
</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js@1.3.x" src="https://code.angularjs.org/1.3.20/angular.js" data-semver="1.3.20"></script>
<script src="app.js"></script>
<script src="myPageableMultiSelect.js"></script>
<script src="mySearchableMultiSelectComponent.js"></script>
</head>
<body ng-controller="MainCtrl">
<p>Hello {{name}}!</p>
<div style='height: 300px;'>
<my-searchable-multi-select-component
my-left-data='availableItemsLeft'
my-right-data='availableItemsRight'
my-page-size='4'
my-left-choice-name='Available'
my-right-choice-name='Selected'
my-left-section-name='Available Items'
my-right-section-name='Selected Items'
></my-searchable-multi-select-component>
</div>
<div style='width: 100%'>
<hr/>
Items in Right list (selected items): <br/> {{availableItemsRight}}
</div>
<hr/><hr/>
<p>Hello {{name}}!</p>
<div style='height: 300px;'>
<my-searchable-multi-select-component
my-left-data='availableItemsLeft'
my-right-data='availableItemsRight'
my-page-size='10'
disable-pagination='true'
disable-search='true'
my-left-choice-name='Available'
my-right-choice-name='Selected'
my-left-section-name='Available Items'
my-right-section-name='Selected Items'
></my-searchable-multi-select-component>
</div>
<div style='width: 100%'>
<hr/>
Items in Right list (selected items): <br/> {{availableItemsRight}}
</div>
</body>
</html>
/* Put your css in here */
button {
margin: 5px;
}
button[disabled=disabled] {
opacity: 0.5;
cursor: not-allowed; /*not sure why not working*/
}
<div>
<select multiple
ng-options='item as item.name for item in myData | filter: (mySearchCondition == "true" ? mySearchString : "") | startFrom: pagination.page * pagination.perPage | limitTo: pagination.perPage'
ng-model='mySelectedItems'
ng-attr-size='{{myPageSize}}'
></select>
<div ng-if='!hidePagination'>
<button ng-disabled='pagination.page == 0' ng-click='gotoFirst()'><<</button>
<button ng-disabled='pagination.page == 0' ng-click='gotoPrev()'><</button>
<button ng-disabled='pagination.page + 1 > pagination.numPages' ng-click='gotoNext()'>></button>
<button ng-disabled='pagination.page + 1 > pagination.numPages' ng-click='gotoLast()'>>></button>
</div>
</div>
app.directive('myPageableMultiSelect', ['$filter', function($filter) {
return {
restrict: 'AE',
scope: {
myData: '=myAvailableOptions',
mySelectedItems: '=mySelectedOptions',
myPageSize: '@',
mySectionName: '@',
mySearchCondition: '@',
mySearchString: '@',
disablePagination: '@'
},
link: function(scope, el, attr) {
el.find('select').css('width', '200px');
var refreshPagination;
if (attr.disablePagination == 'true') {
scope.hidePagination = true;
refreshPagination = function () {
scope.pagination = {
page: 0,
perPage: scope.myData.length,
numPages: 1
};
if (scope.myData.length % scope.myPageSize === 0) {
scope.pagination.numPages--;
}
};
scope.pagination = {
page: 0,
perPage: scope.myData.length,
numPages: 1
};
} else {
scope.hidePagination = false;
refreshPagination = function () {
var displayingData = $filter('filter')(scope.myData, scope.mySearchString);
scope.pagination = {
page: 0,
perPage: scope.myPageSize,
numPages: parseInt(displayingData.length / scope.myPageSize)
};
if (scope.myData.length % scope.myPageSize === 0) {
scope.pagination.numPages--;
}
};
scope.gotoFirst = function() {
scope.pagination.page = 0;
};
scope.gotoLast = function() {
scope.pagination.page = scope.pagination.numPages;
};
scope.gotoPrev = function() {
if (scope.pagination.page > 0) {
scope.pagination.page -= 1;
}
};
scope.gotoNext = function() {
if (scope.pagination.page <= scope.pagination.numPages - 1) {
scope.pagination.page += 1;
}
};
refreshPagination();
}
scope.$watchCollection('myData', function() {
refreshPagination();
});
scope.$watch('mySearchString', function() {
refreshPagination();
});
},
controller: ['$scope', function($scope) {
}],
templateUrl: 'my-pageable-multi-select.html'
};
}]);
<div>
<div ng-if='!hideSeachSection'>
Search: <input ng-model='search.tempSearchStr'/>
<br/>
From:
<input type='radio' value='all' ng-model='search.tempSelection' />All
<input type='radio' value='left' ng-model='search.tempSelection' />{{myLeftChoiceName}}
<input type='radio' value='right' ng-model='search.tempSelection' />{{myRightChoiceName}}
<input type='button' value='Search' ng-click='applySearch()' />
</div>
<br/>
<div style='width: 500px'>
<div style='width: 44%; float: left'>
{{myLeftChoiceName}}
<my-pageable-multi-select
my-available-options='availableItemsLeft'
my-selected-options='selectedItemsLeft'
my-page-size='{{myPageSize}}'
my-section-name='{{myLeftSectionName}}'
my-search-string='{{search.searchStr}}'
my-search-condition='{{search.selection != "right"}}'
disable-pagination='{{disablePagination}}'
></my-pageable-multi-select>
</div>
<div style='width:10%; margin-top: 30px; float: left;'>
<button ng-disabled='availableItemsRight.length == 0' ng-click='addAllItemsToLeft()'><<</button>
<br/>
<button ng-disabled='selectedItemsRight.length == 0' ng-click='addItemToLeft()'><</button>
<br/>
<button ng-disabled='selectedItemsLeft.length == 0' ng-click='addItemToRight()'>></button>
<br/>
<button ng-disabled='availableItemsLeft.length == 0' ng-click='addAllItemsToRight()'>>></button>
</div>
<div style='width: 45%; float: left'>
{{myRightChoiceName}}
<my-pageable-multi-select
my-available-options='availableItemsRight'
my-selected-options='selectedItemsRight'
my-page-size='{{myPageSize}}'
my-section-name='{{myRightSectionName}}'
my-search-string='{{search.searchStr}}'
my-search-condition='{{search.selection != "left"}}'
disable-pagination='{{disablePagination}}'
></my-pageable-multi-select>
</div>
</div>
</div>
app.directive('mySearchableMultiSelectComponent', function() {
return {
restrict: 'AE',
scope: {
myLeftData: '=',
myRightData: '=',
myPageSize: '@',
myRightChoiceName: '@',
myLeftChoiceName: '@',
myRightSectionName: '@',
myLeftSectionName: '@',
disablePagination: '@',
disableSearch: '@'
},
templateUrl: 'my-searchable-multi-select-component.html',
controller: ['$scope', '$filter', function($scope, $filter) {
$scope.availableItemsLeft = $scope.myLeftData;
$scope.availableItemsRight = $scope.myRightData;
$scope.selectedItemsLeft = [];
$scope.selectedItemsRight = [];
$scope.search = {};
$scope.search.tempSearchStr = '';
$scope.search.tempSelection = 'all';
$scope.hideSeachSection =
($scope.disableSearch && $scope.disableSearch === 'true') ? true : false;
$scope.search.searchStr = '';
$scope.search.selection = 'all';
$scope.applySearch = function(){
$scope.search.searchStr = $scope.search.tempSearchStr;
$scope.search.selection = $scope.search.tempSelection;
};
$scope.addAllItemsToLeft = function() {
angular.forEach($scope.availableItemsRight, function(availableItem, key) {
$scope.availableItemsLeft.push(availableItem);
});
$scope.selectedItemsRight.splice(0, $scope.selectedItemsRight.length);
$scope.availableItemsRight.splice(0, $scope.availableItemsRight.length);
};
$scope.addAllItemsToRight = function() {
angular.forEach($scope.availableItemsLeft, function(availableItem, key) {
$scope.availableItemsRight.push(availableItem);
});
//$scope.selectedItemsLeft.splice(0, $scope.selectedItemsLeft.length);
//$scope.availableItemsLeft.splice(0, $scope.availableItemsLeft.length);
$scope.selectedItemsLeft = [];
$scope.availableItemsLeft = [];
};
$scope.addItemToRight = function() {
angular.forEach($scope.selectedItemsLeft, function(selectedItem, key) {
$scope.availableItemsRight.push(selectedItem);
angular.forEach($scope.availableItemsLeft, function(availableItem, index) {
if (availableItem === selectedItem) {
$scope.availableItemsLeft.splice(index, 1);
}
});
});
$scope.selectedItemsLeft.splice(0, $scope.selectedItemsLeft.length);
};
$scope.addItemToLeft = function() {
angular.forEach($scope.selectedItemsRight, function(selectedItem, key) {
$scope.availableItemsLeft.push(selectedItem);
angular.forEach($scope.availableItemsRight, function(availableItem, index) {
if (availableItem === selectedItem) {
$scope.availableItemsRight.splice(index, 1);
}
});
});
$scope.selectedItemsRight.splice(0, $scope.selectedItemsRight.length);
};
}]
};
});