Agzam Agzam - 1 month ago 14
AngularJS Question

ng-options with disabled rows

Is it possible to use

ng-options
that it will render into disabled rows based on criteria?

this:

<select ng-options="c.name group by c.shade for c in colors">


maybe possible to turn into something like this:

<select ng-options="c.name group by c.shade for c in colors | disabled(c.shade)">


and let's say via a filter that could return
disabled='disabled'
for all the colors that have shade = "dark"

<select>
<optgroup label="dark">
<option value="0" disabled="disabled">black</option>
<option value="2" disabled="disabled">red</option>
<option value="3" disabled="disabled">blue</option>
</optgroup>
<optgroup label="light">
<option value="1">white</option>
<option value="4">yellow</option>
</optgroup>
</select>

Answer

I do not believe there is a way to do what you are asking just using ng-options. This issue was raised on the angular project and is still open:

https://github.com/angular/angular.js/issues/638

It seems that the work around is to use a directive which is referenced here and in the github issue: http://jsfiddle.net/alalonde/dZDLg/9/

Here is the entire code from the jsfiddle for reference (the code below is from alande's jsfiddle):

<div ng-controller="OptionsController">
    <select ng-model="selectedport" 
        ng-options="p.name as p.name for p in ports"
        options-disabled="p.isinuse for p in ports"></select>
    <input ng-model="selectedport">
</div>

angular.module('myApp', [])
.directive('optionsDisabled', function($parse) {
    var disableOptions = function(scope, attr, element, data, fnDisableIfTrue) {
        // refresh the disabled options in the select element.
        $("option[value!='?']", element).each(function(i, e) {
            var locals = {};
            locals[attr] = data[i];
            $(this).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.optionsDisabled.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) {
    $scope.ports = [{name: 'http', isinuse: true},
                    {name: 'test', isinuse: false}];

    $scope.selectedport = 'test';
}