Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I have a html select option

<select>
    <option ng-repeat="field in filter.fields" value="{{field.id}}">{{field.name}}</option>
</select>

which I am iterating from ng-repeat , I want to disable option on basis of a filed selectable like

<select>
    <option ng-repeat="field in filter.fields" {field.selectable==true?enable:disable} value="{{field.id}}">{{field.name}}</option>
 </select>

How can I achieve this with angular.

share|improve this question
    
Ordinarily to make a select list with angularjs you're using the ng-options directive though I don't know that it has built in support for disabling options (you may need to copy/tweak the source) the other directive to be aware of that might help with the way you're trying to handle this is ng-disabled docs.angularjs.org/api/ng.directive:ngDisabled –  shaunhusain Sep 10 '13 at 15:21
    
Are you intentionally not binding the value of the select input to a model? –  bibs Sep 10 '13 at 15:30
    
possible duplicate of ng-options with disabled rows –  m59 Sep 10 '13 at 15:32

2 Answers 2

up vote 10 down vote accepted

Assuming you have a structure like this:

  $scope.filter = {
    fields: [
      {id: 1, name: "a", selectable: false},
      {id: 2, name: "asdf", selectable: true},
      {id: 3, name: "qwet", selectable: false},
      {id: 4, name: "qnjew", selectable: true},
      {id: 5, name: "asdjf", selectable: false}
    ]
  };

This should work for you:

  <select>
    <option ng-repeat="field in filter.fields" ng-disabled="field.selectable" value="{{field.id}}">{{field.name}}</option>
  </select>
share|improve this answer
    
Very nice and short solution by you. Thanks It's working fine. –  Satish Sharma Sep 11 '13 at 5:51
    
I'd still recommend you have a look at m59's answer. The problems with my solution that he's highlighting might come back to bite you. –  Kasper Lewau Sep 11 '13 at 6:20

While the ng-disabled attribute will technically work, you are likely to encounter bugs when using ng-repeat on options. This is a well known issue and is exactly the reason that the angular team created ng-options. There is not yet an angular implementation for using ng-options and ng-disabled together, but Alec LaLonde created this custom directive that you can add in and use. See the issue forum here: https://github.com/angular/angular.js/issues/638 and the jsfiddle from that post.

angular.module('myApp', [])
.directive('optionsDisabled', [ '$parse', function($parse) {
        var disableOptions = function($scope, attr, $element, data, fnDisableIfTrue) {
            $element.find('option:not([value="?"])').each(function(i, e) { //1
                var locals = {};
                locals[attr] = data[i];
                $(this).attr('disabled', fnDisableIfTrue($scope, locals));
            });
        };

        return {
            priority: 0,
            require: 'ngModel',
            link: function($scope, $element, attributes) { //2
                var expElements = attributes.optionsDisabled.match(/^\s*(.+)\s+for\s+(.+)\s+in\s+(.+)?\s*/),
                    attrToWatch = expElements[3],
                    fnDisableIfTrue = $parse(expElements[1]);
                $scope.$watch(attrToWatch, function(newValue, oldValue) {
                    if (!newValue) return;

                    disableOptions($scope, expElements[2], $element, newValue, fnDisableIfTrue);
                }, true);

                $scope.$watch(attributes.ngModel, function(newValue, oldValue) { //3
                    var disabledOptions = $parse(attrToWatch)($scope);
                    if (!newValue) return;

                    disableOptions($scope, expElements[2], $element, disabledOptions, fnDisableIfTrue);
                });
            }
        };
    }
]);
//1 refresh the disabled options in the select element
//2 parse expression and build array of disabled options
//3 handle model updates properly

function OptionsController($scope) {
    $scope.ports = [{name: 'http', isinuse: true},
                    {name: 'test', isinuse: false}];

    $scope.selectedport = 'test';
}
share|improve this answer
    
I have updated the referenced JS Fiddle to work with JQLite: link –  HANiS Apr 4 '14 at 10:49

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.