AngularJS Selectable Directive

AngularJS directive to make any element "selectable". Uses AngularJS, Twitter Bootstrap, FontAwesome, CSS, and jQuery

by Danish Farman

HTML

<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
<script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css">
<div ng-app="app" ng-controller="appCtrl">
    <div class="container">
        <div class="row"> <span class="page-header"><h3>Click an item</h3></span>

            <input type="text" class="form-control" ng-model="activeItem" />
        </div>
        <div class="row mainbox">
            <div id="item{{item.value}}" ng-repeat="item in items" class="boxes col-xs-6 card bg-{{ item.value }}" selectable="setActiveItem(item.value)"><i class="fa fa-check fa-inverse fa-lg" ng-show="activeItem == item.value"></i><span ng-hide="activeItem == item.value">{{ item.display }}</span>
            </div>
        </div>
    </div>
</div>

CSS

.card {
    width:20%;
    border: 1px solid #ccc;
    border-radius: 5px;
    margin: 5px;
    text-align: center;
    padding-top: 20px;
    padding-bottom: 20px;
    cursor: pointer;
    color: Black;
}
.active {
    background-color: #5cb85c;
}
.mainbox {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
}
.boxes {
    border: 2px solid orange;
    padding: 5px;
    margin: 5px;
    width: 20%;
    text-align: center;
    font-family: tahoma;
    font-size: medium;
    font-weight: bold;
}
#itemone {
    background-image: linear-gradient(blue, white);
}
#itemtwo {
    background-image: linear-gradient(red, white);
}
#itemthree {
    background-image: linear-gradient(green, white);
}
#itemfour {
    background-image: linear-gradient(yellow, white);
}
#itemfive {
    background-image: linear-gradient(orange, white);
}
#itemsix {
    background-image: linear-gradient(purple, white);
}
#itemseven {
    background-image: linear-gradient(magenta, white);
}
#itemeight {
    background-image: linear-gradient(skyblue, white);
}

JavaScript

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

mod.controller('appCtrl', function ($scope) {
    $scope.activeItem = '';
    $scope.items = [{
        display: 'Item 1',
        value: 'one'
    }, {
        display: 'Item 2',
        value: 'two'
    }, {
        display: 'Item 3',
        value: 'three'
    }, {
        display: 'Item 4',
        value: 'four'
    }, {
        display: 'Item 5',
        value: 'five'
    }, {
        display: 'Item 6',
        value: 'six'
    }, {
        display: 'Item 7',
        value: 'seven'
    }, {
        display: 'Item 8',
        value: 'eight'
    }, ];

    $scope.setActiveItem = function (val) {
        $scope.activeItem = val;
    };
});

mod.directive('selectable', function () {
    return {
        restrict: 'A',
        link: function (scope, element, attrs) {
            element.bind('click', function (e) {
                $(".active").each(function () {
                    //$(this).removeClass('active');                
                });
                element.addClass('active');
                var itemsCollection = [];
                itemsCollection.push({
                    value: scope.item.value,
                    display: scope.item.display
                })
                // have to disable the selected item in view after click
                for (var i = 0; i < itemsCollection.length; i++) {
                    console.log(itemsCollection[i]);
                }
                scope.$apply(attrs.selectable);
            });
        }
    }
});