Angular: name value select directive
A directive that allows to match server-side "Enums" (values) with client-side user-friendly descriptions (names)
HTML
<script src="http://code.angularjs.org/1.0.0/angular-1.0.0.js"></script>
<link rel="stylesheet" href="http://twitter.github.com/bootstrap/assets/css/bootstrap.css">
<script src="https://raw.github.com/documentcloud/underscore/master/underscore.js"></script>
<div ng-app="myApp" ng-controller="ListCtrl">
<h3>Data source</h3>
original {{master}}
<hr>
<h3>Edit section</h3>
copy under editing {{entry}}
<br><br>
<h6>Change select to affect copy</h6>
<name-value-select entry="entry" field="type" options="types" on-input-change="onInputChange()"></name-value-select>
<div ng-show='edited'>
<br>
<h6>Update or discard changes</h6>
<button class='btn btn-primary' ng-click='update()'>Update changes</button>
<button class='btn' ng-click='cancel()'>Cancel changes</button>
</div>
</div>
JavaScript
var myApp = angular.module('myApp', []);
function Entry(obj) {
var that = {};
_.extend(that, obj);
that.clone = function() {
return angular.copy(that);
};
that.update = function(data) {
_.extend(that, data);
};
return that;
}
myApp.directive('nameValueSelect', function() {
return {
restrict: "E",
scope: {
entry: "=",
field: "@",
options: "=",
onInputChange: "&"
},
controller: function($scope) {
$scope.onChange = function() {
console.log("selected changed");
$scope.entry.type = $scope.option.value;
$scope.onInputChange();
};
var getItemForValue = function(value) {
var item = null;
$scope.options.forEach(function(_option) {
if (_option.value == value) {
item = _option;
}
});
return item;
};
$scope.$watch("entry", function() {
console.log("entry changed");
$scope.option = getItemForValue($scope.entry[$scope.field]);
}, true);
},
template: '<select ng-model="option" ng-options="o.name for o in options" ng-change="onChange()">'
};
});
myApp.controller('ListCtrl', function($scope) {
$scope.master = new Entry({
name: 'Marco'
});
$scope.master.type = "AUTHORIZED";
$scope.entry = $scope.master.clone();
$scope.types = [
{
value: "AUTHORIZED",
name: "Authorized"},
{
value: "NOT_AUTHORIZED",
name: "Not authorized"}
];
$scope.edited = false;
$scope.onInputChange = function() {
console.log('controller on change');
$scope.edited = true;
};
$scope.update = function() {
$scope.master.update($scope.entry);
$scope.edited...