Custom select directive for styling & padding
by Ayyappan Sakthivadivel
HTML
<script src="https://cdn.rawgit.com/epeli/underscore.string/master/dist/underscore.string.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css">
<div ng-app="demoApp" ng-controller="mainCtrl as ctrl">
<h3>
Custom directive styled as select with table for padding
</h3>
<my-select ng-model="ctrl.selection" data="ctrl.selectData"></my-select>
<br/> {{ctrl.selection}}
<h3>
Select with ng-repeat and formtString method
(updating not working properly)
</h3>
<select ng-model="ctrl.selection">
<option ng-repeat="trink in ctrl.selectData" ng-bind-html="ctrl.formatString(trink)" value="{{trink}}"></option>
</select>
<h3>
Select wiht ng-options (no padding)
</h3>
<select ng-model="ctrl.selection" ng-options="trink as (trink.name+ ' ' + trink.size + ' ' + trink.units) for trink in ctrl.selectData"></select>
<script type="text/ng-template" id="components/selectionDirTmpl.html">
<div class="selectBox" ng-click="selectCtrl.open()">
<div class="selectBox-title">{{selectCtrl.selection}}
<i class="fa fa-chevron-down pull-right chevron-box" id="test" aria-hidden="true"></i>
</div>
<table ng-if="selectCtrl.visible">
<tr ng-repeat="item in selectCtrl.data">
<td ng-repeat="(key,value) in item" colspan="{{key === 'empty'? Utils.keys(selectCtrl.data[1]).length - 1: ''}}" ng-click="selectCtrl.select(item)">{{value}}</td>
</tr>
</table>
</div>
</script>
</div>
CSS
select {
font-family: "Lucida Console", Monaco, monospace;
/*white-space: pre;*/
}
.selectBox {
position: relative;
font-family: Arial, Helvetica Neue, Helvetica, sans-serif;
width: 250px;
cursor: default;
}
.selectBox-title {
border: 1px solid lightgray;
padding: 0.5em;
line-height: 1em;
min-height: 1em;
}
div .selectBox-title:hover {
border: 1px solid black;
}
.selectBox table {
width: 100%;
position: absolute;
top: 2em;
left: 0;
border-collapse: collapse;
background-color: rgba(255, 255, 255, 0.9);
border: 1px solid gray;
padding: 0.5em;
white-space: pre;
}
.selectBox tr:hover {
background-color: lightblue;
}
.selectBox td {
padding: 0.5em;
}
.pull-right {
float: right;
}
JavaScript
// for this SO
// http://stackoverflow.com/questions/37768742/how-to-make-hmtl-markup-show-correctly-in-angularjs-binding-using-a-function/37768855#37768855
angular.module('demoApp', [])
.directive('mySelect', MySelectDir)
.controller('mainCtrl', MainCtrl);
function MySelectDir($document, $parse) {
return {
scope: {
ngModel: '=',
data: '='
},
controllerAs: 'selectCtrl',
controller: function($scope, $element, $attrs) {
var vm = this,
localData = Object.create($scope.data); // use local copy so we can add empty option
$scope.Utils = {
keys : Object.keys
};
//$scope.data = angular.copy($scope.data);
function dismissClick(e) {
if ($element !== e.target && !$element[0].contains(e.target)) {
console.log('dismiss', vm.visible);
vm.visible = false;
$document.off('click', dismissClick);
$scope.$apply();
}
}
function createCaption(model) {
var caption = '';
angular.forEach(model, function(value, key) {
if (key !== '$$hashKey' && value !== null) {
caption += ' ' + value;
}
});
return caption;
}
angular.extend(vm, {
visible: false,
data: localData,
selection: {},
select: function(item) {
var index = vm.data.indexOf(item);
$scope.ngModel = vm.data[index].empty === null ? {} :
vm.data[index];
vm.selection = createCaption(vm.data[index]);
},
addDismissClick: function() {
$document.on('click', dismissClick);
...