Skip to content

Instantly share code, notes, and snippets.

@blakedietz
Last active August 29, 2015 14:15
Show Gist options
  • Save blakedietz/02b884ad487526fc6d66 to your computer and use it in GitHub Desktop.
Save blakedietz/02b884ad487526fc6d66 to your computer and use it in GitHub Desktop.
A small example of a multi-select component.
angular.module( 'exampleApplication', [] )
.controller( 'selectionController', function( $scope )
{
$scope.selectedItems = _.range( 0, 24 )
.map( function( number )
{
return {
"name": number
}
} );
$scope.selectableItems = [
{
"name": 24
} ];
$scope.aSelection;
$scope.replaceItemInSelectedItemsWithNewlySelectedItem = function( selectable, current )
{
var currentIndex = _.findIndex( $scope.selectedItems,
function( item )
{
return current.name === item.name;
} );
var itemToSwitchWithCurrentSelection = removeFromSelecableItems( selectable );
var currentSelection = removeFromSelectedItems( current );
$scope.selectedItems.splice( currentIndex, 0, itemToSwitchWithCurrentSelection );
addToSelectableItems( currentSelection );
};
$scope.selectUnselectedItem = function( selectable )
{
var selectedItem = removeFromSelecableItems( selectable );
$scope.selectedItems.push( selectedItem );
$scope.aSelection = null;
};
$scope.removeCurrentSelection = function( currentlySelected )
{
var selectionToRemove = removeFromSelectedItems( currentlySelected );
addToSelectableItems( selectionToRemove );
};
function removeFromSelectedItems( itemToRemove )
{
return _.remove( $scope.selectedItems,
function( item )
{
return itemToRemove.name === item.name;
} )[ 0 ];
}
function removeFromSelecableItems( itemToRemove )
{
return _.remove( $scope.selectableItems,
function( item )
{
return itemToRemove.name === item.name;
} )[ 0 ];
}
function addToSelectableItems( itemToAdd )
{
$scope.selectableItems.push( itemToAdd );
$scope.selectableItems = _.sortBy( $scope.selectableItems, 'name' );
}
} )
.directive( 'selectedItem', function()
{
return {
restrict: 'AE',
templateUrl: 'selection-directive.tpl.html',
scope:
{
selectableItems: '=',
selectedItem: '=',
changeHandler: '=',
removeHandler: '='
},
link: function( scope, elements, attributes )
{
scope.currentItem = null;
scope.$watch( 'selectedItem', function( old, newItem )
{
if ( newItem )
{
scope.currentItem = scope.selectedItem;
}
} );
}
};
} );
<!DOCTYPE html>
<html>
<head>
<title>Multi Select Example</title>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.13/angular.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.2.0/lodash.js"></script>
<script type="text/javascript" src="https://gist.githubusercontent.com/blakedietz/02b884ad487526fc6d66/raw/cb023b882cc5070daafc19c4c4095f190b553141/example.js"></script>
</head>
<body ng-app="exampleApplication" ng-controller="selectionController">
<!-- Template for single selection directive -->
<script type="text/ng-template" id="selection-directive.tpl.html">
<div>
<select name="" id=""
ng-model="selectedItem"
ng-options="selectable.name for selectable in selectableItems"
ng-change="changeHandler(selectedItem, currentItem)">
<option value="">
{{selectedItem.name}}
</option>
</select>
<button ng-click="removeHandler(selectedItem)">Remove</button>
</div>
</script>
<div
ng-repeat="selectedItem in selectedItems"
selected-item="selectedItem"
selectable-items="selectableItems"
change-handler="replaceItemInSelectedItemsWithNewlySelectedItem"
remove-handler="removeCurrentSelection"
>
</div>
<div ng-show="selectableItems.length">
<select name="" id="" ng-model="aSelection" ng-options="selectable.name for selectable in selectableItems" ng-change="selectUnselectedItem(aSelection)">
<option value="">
Select something
</option>
</select>
</div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment