StackOverflow_24631325: customize-ng-options-selection-look
Illustration of answer to http://stackoverflow.com/questions/24631325/customize-ng-options-selection-look.
by ExpertSystem
HTML
<script src="http://code.angularjs.org/1.2.19/angular.min.js"></script>
<div ng-controller="myCtrl">
<h4>
Approach 1 -
<small>(Using <option> and binding to strings)</small>
</h4>
<select ng-model="color">
<option value="">--- Select a color ---</option>
<option value="{{c}}" style="background-color:{{c}}"
ng-repeat="c in colors">
{{c}}
</option>
</select>
<p>Selected color: <b style="color:{{color}}">{{color}}</b></p>
<hr />
<h4>
Approach 2 -
<small>(Using ngOptions and binding to objects)</small>
</h4>
<select ng-model="obj" ng-options="o as o.color for o in objects"
option-class-expr="color.toLowerCase()">
<option value="">--- Select a color ---</option>
</select>
<p>Selected object: <b style="color:{{obj.color}}">{{obj | json}}</b></p>
<button ng-click="addBlackAndWhite()" ng-disabled="added"
title="Adds a Black and a White option">
Add Black & White
</button>
<button ng-click="revBlackAndWhite()" ng-disabled="!added||reversed"
title="Reverses the Black and the White option">
Reverse Black & White
</button>
<br />
<small>
<ol>
The buttons are used just to showcase live updating of classes, when:
<li>either new objects are added or</li>
<li>existing objects are updated</li>
</ol>
</small>
<hr />
<h4>
Approach 3 -
<small>(Similar to 2 but does NOT adapt to "runtime" changes)</small>
</h4>
<select ng-model="status" ng-options="s as s.label for s in statuses"
option-class-expr-static="{true:'active',false:'inactive'}[value]">
<option value="">--- Select a status ---</option>
</select>
<p>
Selected status:
<b ng-class="{active:status.value===true,
inactive:status.value===false}">
...
CSS
p { background-color: LightGray; }
.blue { background-color: Blue; }
.cyan { background-color: Cyan; }
.green { background-color: Green; }
.orange { background-color: Orange; }
.pink { background-color: Pink; }
.purple { background-color: Purple; }
.red { background-color: Red; }
.black {
background-color: Black;
color: White;
}
.White {
background-color: White;
color: Black;
}
.active {
background-color: DarkGreen;
color: LimeGreen;
}
.inactive {
background-color: DarkRed;
color: LightGray;
}
JavaScript
var app = angular.module('myApp', []);
app.controller('myCtrl', function ($scope) {
$scope.colors = ['Blue', 'Cyan', 'Green', 'Orange', 'Pink', 'Purple', 'Red'];
$scope.objects = [
{id: 1, color: 'Blue'},
{id: 2, color: 'Cyan'},
{id: 3, color: 'Green'},
{id: 4, color: 'Orange'},
{id: 5, color: 'Pink'},
{id: 6, color: 'Purple'},
{id: 7, color: 'Red'}
];
$scope.statuses = [
{label: 'Active', value: true},
{label: 'Inactive', value: false}
];
$scope.addBlackAndWhite = function () {
$scope.objects.push({id: 8, color: 'Black'});
$scope.objects.push({id: 9, color: 'White'});
$scope.added = true;
};
$scope.revBlackAndWhite = function () {
$scope.objects[7].color = 'White';
$scope.objects[8].color = 'Black';
$scope.reversed = true;
};
});
app.directive('optionClassExpr', function ($compile, $parse) {
var NG_OPTIONS_REGEXP = /^\s*([\s\S]+?)(?:\s+as\s+([\s\S]+?))?(?:\s+group\s+by\s+([\s\S]+?))?\s+for\s+(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))?$/;
return {
restrict: 'A',
link: function optionClassExprPostLink(scope, elem, attrs) {
var optionsExp = attrs.ngOptions;
if (!optionsExp) return;
var match = optionsExp.match(NG_OPTIONS_REGEXP);
if (!match) return;
var values = match[7];
scope.$watchCollection(function () {
return elem.children();
}, function (newValue) {
angular.forEach(newValue, function (child) {
var child = angular.element(child);
var val = child.val();
if (val) {
child.attr('ng-class', values + '[' + val + '].' +
...