Search code examples
javascriptangularjsangularjs-ng-disabled

What is the 'AngularJS' way to disable an 'option' HTML5 element?


What is the 'AngularJS' way to disable an 'option' HTML5 element?

I'm using AngularJS v1.2.25.

Plunk Link: https://plnkr.co/edit/fS1uKZ

<!-- CODE BEGIN -->
<!DOCTYPE html>
<html>
    <head>
        <script data-require="[email protected]" data-semver="2.0.0" src="https://code.angularjs.org/2.0.0-beta.6/angular2.min.js"></script>
        <link rel="stylesheet" href="style.css" />
        <script src="script.js"></script>
    </head>
    <body>
        <select>
            <option value="volvo">Volvo</option>
            <option value="saab">Saab</option>
            <option value="opel">Opel</option>
            <option value="audi">Audi</option>
        </select>
        <select>
            <option value="volvo">Volvo</option>
            <option value="saab">Saab</option>
            <option value="opel">Opel</option>
            <option value="audi">Audi</option>
        </select>
        <select>
            <option value="volvo">Volvo</option>
            <option value="saab">Saab</option>
            <option value="opel">Opel</option>
            <option value="audi">Audi</option>
        </select>
        <select>
            <option value="volvo">Volvo</option>
            <option value="saab">Saab</option>
            <option value="opel">Opel</option>
            <option value="audi">Audi</option>
        </select>
    </body>
</html>
<!-- CODE END -->

I'm making a 'form' element and there are several 'select' element tags with several 'option' element tags.

The 'option' element tags have identical attributes throughout all four of the 'select' element tags.

I want the user to rank the car manufacturers. When they select a manufacturer, I want to disable that 'option' element in all four 'select' element tags.

I found the following question/answer, but is this the 'AngularJS' way? (Disable option in select)

They are using jQuery and I know that AngularJS contains 'jQuery Lite', but is that implementation the 'AngularJS' way?

I found this documentation at the AngularJS site: htt9$://docs.angularjs.org/api/ng/directive/ngDisabled

This is the accompanying Plunk link: htt9$://plnkr.co/edit/?p=preview

I can appreciate the example provided by the AngularJS team. I was thinking about modifying ng-model and/or ng-disabled. I would like to avoid 'hacking' AngularJS 'core' files.

Do I decouple ng-model and/or ng-disabled?

Or, should I craft a custom filter?

I come from a jQuery background, and I'm trying to adhere to AngularJS best practices as much as possible. I want to prevent excessive 'technical debt'.


Solution

  • The Angular way to disable a select option is to use ng-disabled="expression" This plunker shows how it's done.

    In you case you can have 4 selects like so:

    <select ng-model="model.selected1">
      <option ng-repeat="c in model.options" value="{{c.value}}" ng-disabled="model.should_disable(c, 1)">{{c.label}}</option>
    </select>
    <select ng-model="model.selected2">
      <option ng-repeat="c in model.options" value="{{c.value}}" ng-disabled="model.should_disable(c, 2)">{{c.label}}</option>
    </select>
    <select ng-model="model.selected3">
      <option ng-repeat="c in model.options" value="{{c.value}}" ng-disabled="model.should_disable(c, 3)">{{c.label}}</option>
    </select>
    <select ng-model="model.selected4">
      <option ng-repeat="c in model.options" value="{{c.value}}" ng-disabled="model.should_disable(c, 4)">{{c.label}}</option>
    </select>
    

    where model.options is your list of options

    var model = $scope.model = {
        options: [
          {label: 'Volvo', value: 'volvo'},
          {label: 'Audi', value: 'audi'},
          {label: 'Saab', value: 'saab'},
          {label: 'Opel', value: 'opel'},
        ],
        should_disable: should_disable
    }
    

    That function should_disable(c, num) is supposed to be true when car c is selected in a <select> other than num.

      function should_disable(c, selectnum){
        var other_selectnums = [1,2,3,4].filter(function(n){
          return n != selectnum;
        });
        var is_selected_somewhere_else = false;
        for(var i=0; i<other_selectnums.length; i++){
          var otherselectnum = other_selectnums[i];
          if(c.value == model['selected'+otherselectnum]){
            is_selected_somewhere_else = true;
            break;
          }
        }
        return is_selected_somewhere_else;
      }
    

    Here's a fully working plunkr