0

Now I am trying to select box with disabled.

When $shop.products.product[i].productId is changed by selectBox, I want that value disabled in select box option.

for example, if i select 3 in select box on second row, then select box option 1,3 are disabled.

so i register $watch witch resync isDisabled field when $shop.products[i].productId is changed.

i don't know why $watch is no calling. help me please.

// Code goes here

angular.module("myApp")
    .controller("myCtrl", function($scope) {
      
        $scope.shop = {
          "id" : 'shop1',
          "products" : [
            {"productId" : 1,"desc" : 'product1'},
            {"productId" : 2,"desc" : 'product2'}
          ]
        };
      
        $scope.allSelectBoxItems = [
          {"id" : 1, "isDisabled" : true}, 
          {"id" : 2, "isDisabled" : true}, 
          {"id" : 3, "isDisabled" : false}, 
          {"id" : 4, "isDisabled" : false}
        ];
        
        $scope.addWatcher = function(index){
            console.log('register watcher to ' + index);
            $scope.$watch('shop.product[' + index + '].productId', function(newValue, oldValue){
              console.log('watcher envoked');
              if (newValue != oldValue) {
                var selected = $scope.shop.products.map(function (product) {
                    return product.productId;
                });

                for (var i = 0; i < $scope.allSelectBoxItems.length; i++) {
                    var isSelected = selected.includes($scope.allSelectBoxItems[i].productId);
                    console.log(isSelected);
                    $scope.allSelectBoxItems.isDisabled = isSelected;
                }
            }
            }); 
        }
        
        angular.forEach($scope.shop.products, function(value, index){
          $scope.addWatcher(index);  
        });
        
      
        $scope.addProduct = function(){
          var nextProductId = $scope.shop.products.length + 1;
          var newProduct = {"productId" : nextProductId ,"desc" : 'product' + nextProductId};
          
          $scope.shop.products.push(newProduct);
          $scope.addWatcher(nextProductId - 1);
        }
        
      
    });
<!DOCTYPE html>
<html ng-app="myApp">

  <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
    <script src="https://code.angularjs.org/1.6.4/angular.min.js"></script>
    <script src="https://code.angularjs.org/1.6.4/angular-animate.min.js"></script>
    <script src="https://code.angularjs.org/1.6.4/angular-touch.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/2.5.0/ui-bootstrap-tpls.min.js"></script>
    <script>
      angular.module("myApp", ['ngAnimate', 'ui.bootstrap'])
    </script>
    <script src="script.js"></script>
  </head>

  <body ng-controller="myCtrl">
    <div>
      <table class="table">
        <tbody>
          <tr>
            <th>id</th>
            <td>{{shop.id}}</td>
          </tr>
          <tr>
            <td>
              products
              <br>
              <button type="button" class="btn btn-default" ng-click="addProduct()"><span class="glyphicon glyphicon-plus" aria-hidden="true" style="margin-right:4px"></span>add product</button>
            </td>
            <td>
              <table class="table">
                <tbody>
                  <tr>
                    <td>producId</td>
                    <td>desc</td>
                  </tr>
                  <tr ng-repeat="product in shop.products">
                    <td>
                      <select ng-model="product.productId" ng-options="selectBoxItem.id as selectBoxItem.id disable when selectBoxItem.isDisabled for selectBoxItem in allSelectBoxItems"></select>
                    </td>
                    <td>
                      {{product.desc}}
                    </td>
                  </tr>
                </tbody>
              </table>
            </td>
          </tr>
        </tbody>
      </table>
    </div>
  </body>

</html>
hwyoo
  • 11
  • 3
  • I believe there is a typo: `$scope.$watch('shop.product[' + index + '].productId' ...` should be `$scope.$watch('shop.products[' + index + '].productId' ...`. You refer to `shop.product[i].productId`, but that should be `shop.products[i].productId` –  Jun 28 '18 at 12:52
  • and another problem: var isSelected = selected.includes($scope.allSelectBoxItems[i].productId); productId is not a valid value it should be id. This appraoch is wrong and very difficult to implement, plus if it works, the user wont be able to change their choices after they have selected everything, unless they delete. I recomend you look into duplicate validation to tell the user they have made a duplicate choice. – Axar Jun 28 '18 at 12:59
  • oh.. thanks..but after fix typo. other problem present. – hwyoo Jun 28 '18 at 13:05
  • thanks Axr. my real project has delete button. but i consider your opinion. thanks – hwyoo Jun 28 '18 at 13:26
  • Possible duplicate of [angularJs select value is null](https://stackoverflow.com/questions/51084489/angularjs-select-value-is-null) – DanteTheSmith Jun 28 '18 at 14:38

0 Answers0