//Inspired by http://stackoverflow.com/questions/16202254/ng-options-with-disabled-rows/20790905#20790905
//Written by David Votrubec from ST-Software
//up-to-date code is on Github! https://github.com/ST-Software/STAngular/blob/master/src/directives/SgOptionsDisabled
//this issue should be fixed by Angular 1.4
angular.module('myApp', [])
.directive('sgOptionsDisabled', function ($parse) {
var disableOptions = function (scope, attr, element, data, fnDisableIfTrue) {
// refresh the disabled options in the select element.
var containsEmptyOption = element.find("option[value='']").length != 0;
angular.forEach(element.find("option"), function (value, index) {
var elem = angular.element(value);
if (elem.val() != "") {
var locals = {};
//ST-Software modification (index-1 because of the initial empty option)
var i = containsEmptyOption ? index - 1 : index;
locals[attr] = data[i];
elem.attr("disabled", fnDisableIfTrue(scope, locals));
}
});
};
return {
priority: 0,
require: 'ngModel',
link: function (scope, iElement, iAttrs, ctrl) {
// parse expression and build array of disabled options
var expElements = iAttrs.sgOptionsDisabled.match(/^\s*(.+)\s+for\s+(.+)\s+in\s+(.+)?\s*/);
var attrToWatch = expElements[3];
var fnDisableIfTrue = $parse(expElements[1]);
scope.$watch(attrToWatch, function (newValue, oldValue) {
if (newValue)
disableOptions(scope, expElements[2], iElement, newValue, fnDisableIfTrue);
}, true);
// handle model updates properly
scope.$watch(iAttrs.ngModel, function (newValue, oldValue) {
var disOptions = $parse(attrToWatch)(scope);
if (newValue)
disableOptions(scope, expElements[2], iElement, disOptions, fnDisableIfTrue);
});
}
};
});
function OptionsController($scope) {
var options = [
{id:1, name: 'enabled option 1', disabled: false},
{id:2, name: 'disabled option 2', disabled: true},
{id:3, name: 'disabled option 3', disabled: true},
{id:4, name: 'enabled option 4', disabled: false},
{id:5, name: 'enabled option 5'},
];
$scope.options = options;
$scope.myOption = options[1].id;
$scope.myOption2 = options[1].id;
}
<div ng-controller="OptionsController">
<!-- Without empty option -->
<select ng-model="myOption"
ng-options="o.id as o.name for o in options"
sg-options-disabled="o.disabled == true for o in options"></select>
<div ng-bind="myOption"></div>
<br/>
<br/>
<br/>
<!-- With empty option -->
<select ng-model="myOption2"
ng-options="o.id as o.name for o in options"
sg-options-disabled="o.disabled == true for o in options">
<option value=""></option>
</select>
<div ng-bind="myOption2"></div>
</div>
External resources loaded into this fiddle: