简体   繁体   中英

Angular to disable ng-repeat checkbox based on value

I have a list of checkbox displayed using ng-repeat, now i need to disable some checkbox based on specific value checkbox is checked.

checkbox display code

<div class="checkbox">
     <label ng-repeat="specific in specifications">
          <input ng-click="onClick(specific, newObject[specific])" id="specifications_chk" value="{{specific}}" ng-model="newObject[specific]" type="checkbox">
          {{specific}}
     </label>
</div>

Here am using ng-click function to disable checkbox.

This is my controller code:

$scope.onClick = function(sp, checked){
        if(sp == 'Sofa_Cleaning' && checked === true){
            angular.element(document.getElementById('specifications_chk'))[0].disabled = true;
        }

        if(sp == 'Sofa_Cleaning' && checked === false){
            angular.element(document.getElementById('specifications_chk'))[0].disabled = false;
        }

    };

html view:

in controller code am able disable only first value (IndepthHomeCleaning) , so how can i disable Room_Cleaning, Kitchen_Cleaning, and Carpet_cleaning when Sofa_Cleaning is checked 复选框视图

Am i stuck with this, Help will be really appreciated

I don't know why you are still stick with the jquery. You are getting by id when you are trying to disable the checkbox.

.

In html, id should be unique for the current html page. y ou are having duplicated ids and you are getting the first value from the array using [o] when you are trying to disable.

.

If you strictly want solution from the same method then use the following methodology Use class name instead of id for the check boxes and use angular element and disable.

The following code should be used where you need to disable. Use appropriate code based on your need.

    angular.forEach(document.getElementsByClassName('checkbox1'), function(value, key) {
        angular.element(value)[0].disabled = true;
        debugger
  });

use ng-disabled

 var angApp = angular.module('myApp', []); angApp.controller('MyController', function MyController($scope) { $scope.specifications = [{"text":"IndepthHomeCleaning ", "disabled":false, "checked":false}, {"text":"Room_Cleaning", "disabled":false, "checked":false}, {"text":"Kitchen_Cleaning", "disabled":false, "checked":false}, {"text":"BathroomCleaning", "disabled":false, "checked":false}, {"text":"Carpet_cleaning", "disabled":false, "checked":false}, {"text":"Sofa_Cleaning", "disabled":false, "checked":false}]; $scope.onClick = function(sp, checked){ console.log(sp, checked); if(sp.text == 'Sofa_Cleaning' && checked){ $scope.specifications[1].disabled = true; $scope.specifications[2].disabled = true; $scope.specifications[4].disabled = true; } if(sp.text == 'Sofa_Cleaning' && !checked){ $scope.specifications[1].disabled = false; $scope.specifications[2].disabled = false; $scope.specifications[4].disabled = false; } }; }); 
 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> <div ng-app="myApp" ng-controller="MyController"> <div class="checkbox"> <label ng-repeat="specific in specifications" style="display:block"> <input ng-disabled="specific.disabled" ng-change="onClick(specific, specific.checked)" id="specifications_chk" value="specific.checked}" ng-model="specific.checked" type="checkbox"> {{specific.text}} </label> </div> </div> 

I think you're over complicating this. Your data object should be simplified to look like this

$scope.specifications = [
    {name: 'Sofa_Cleaning', active: false},
    {name: 'Carpet_Cleaning', active: false},
    {name: 'Room_Cleaning', active: false},
    {name: 'Kitchen_Cleaning', active: false},
    {name: 'BathroomCleaning', active: false}
];

Template:

<input type="checkbox"
    ng-bind="specific.name" 
    ng-model="specific.active"
    ng-disabled="shouldDisable(specific)">

in your controller

$scope.disableWhenSofaIsChecked = ['Room_Cleaning','Kitchen_Cleaning','Carpet_Cleaning'];
$scope.shouldDisable = function(specific) {
    var disable = $scope.disableWhenSofaIsChecked;
    if(disable.indexOf(specific.name) > -1) {
        for(var obj in $scope.specifications) {
            if(obj.name === 'Sofa_Cleaning') {
                return obj.active;
            }
        }
    }
    return false;
}

EDIT

So if you're getting specifications data from API, you can just do this:

SomeApi
    .get()
    .then(function(results){
        // Assuming it's a promise. End result is the same for a passed-in callback
        // Assuming results is an array of names 
        $scope.specifications = results.map(function(item){
            return {
                name: item,
                active: false
            };
        });
    });

You should not have same id for multiple elements in your code. You need to make you elements ids unique.

HTML :

<div ng-app ng-controller="LoginController">
  <div class="checkbox">
    <label ng-repeat="specific in specifications">
      <input id="specifications_chk{{$index}}" ng-click="onClick(specific, newObject[specific])" value="{{specific}}" ng-model="newObject[specific]" type="checkbox" /> {{specific}}
      <br>
    </label>
  </div>
</div>

JavaScript :

function LoginController($scope) {
  $scope.specifications = ['IndepthHomeCleaning',
    'Room_Cleaning',
    'Kitchen_Cleaning',
    'BathroomCleaning',
    'Carpet_cleaning',
    'Sofa_Cleaning'
  ];
  $scope.newObject = {
    'IndepthHomeCleaning': 1,
    'Room_Cleaning': 2,
    'Kitchen_Cleaning': 3,
    'BathroomCleaning': 4,
    'Carpet_cleaning': 5,
    'Sofa_Cleaning': 6
  };
  $scope.onClick = function(sp, checked) {
    if (sp == 'Sofa_Cleaning' && checked === true) {
      angular.element(document.getElementById('specifications_chk1'))[0].disabled = true;
      angular.element(document.getElementById('specifications_chk2'))[0].disabled = true;
      angular.element(document.getElementById('specifications_chk4'))[0].disabled = true;
    }

    if (sp == 'Sofa_Cleaning' && checked === false) {
      angular.element(document.getElementById('specifications_chk1'))[0].disabled = false;
      angular.element(document.getElementById('specifications_chk2'))[0].disabled = false;
      angular.element(document.getElementById('specifications_chk3'))[0].disabled = false;
    }


  };
}

JsFiddle : https://jsfiddle.net/nikdtu/f7k3kcwn/

You are using 'id' attribute which should be unique for each DOM element. So definitely your solution will take single element. So you should try using class attribute and document.getElementbyClass function.

If you want to change specifications array you need a new array and mapping. Define new row object for each specification. Access specification row and its prop (is active or is disable) from your specification.

http://jsfiddle.net/ms403Ly8/87/

function testCtrl($scope, $filter) {
$scope.specifications = ["IndepthHomeCleaning", "Room_Cleaning", "Kitchen_Cleaning", "Carpet_cleaning", "Sofa_Cleaning"];
$scope.specificationRows = [];

$scope.newRow = function(spec) {
    var newSpec = {
        SpecName: spec,
        IsDisabled: false,
        IsClicked: false
    };
    $scope.specificationRows.push(newSpec);
};

$scope.getRowObject = function(sp) {
    return $filter('filter')($scope.specificationRows, {
        SpecName: sp
    })[0];
};

$scope.getRowStatus = function(spec) {
    console.log($filter('filter')($scope.specificationRows, {
        SpecName: spec
    })[0].IsDisabled);
    return $scope.getRowObject(spec).IsDisabled;
};

$scope.onClick = function(sp) {
    $scope.getRowObject(sp).IsClicked = !$scope.getRowObject(sp).IsClicked;
    if (sp == 'Sofa_Cleaning') {
        $scope.getRowObject("Carpet_cleaning").IsDisabled = $scope.getRowObject(sp).IsClicked;
        $scope.getRowObject("Kitchen_Cleaning").IsDisabled = $scope.getRowObject(sp).IsClicked;
        $scope.getRowObject("Room_Cleaning").IsDisabled = $scope.getRowObject(sp).IsClicked;
    }
};

}

getRowObject is example. Maybe it's not best practice. You can change this function.

Don't use jquery to for dom manipulation.

Use ng-change instead of ng-click. This will be the appropriate one.

Here I've update a plunkr.

Here for the simple example, I've done like if the value is check5 then disable all the checkboxes. Otherwise enable the checkboxes.

https://jsfiddle.net/AvGKj/517/

Note : I've used little bit old plugin. Please take the logics alone

<div ng-controller="MyCtrl">
    <table>
    <tr ng-repeat="appObj in myAppObjects">
        <td>
        <input type="checkbox" ng-model="appObj.cb1"
        ng-disabled="appObj.disable"
        ng-change="Disable(appObj,myAppObjects)">
        {{appObj.value}}
            </td>
    </tr>
    </table>
    {{myAppObjects}}
    <br>list of checked items: {{checkedItems()}}
</div>

function MyCtrl($scope) {

        $scope.myAppObjects = [
       {id:1,value:'check1'},
       {id:2,value:'check2'},
       {id:3,value:'check3'},
       {id:4,value:'check4'},
       {id:5,value:'check5'}
       ];

      $scope.Disable=function(appObj,list)
      {
        if(appObj.value=="check5")
        {
             for(var i=0; i<list.length;i++)
           {
           if(list[i].value!="check5")
              {
                if(appObj.cb1==true)
                {
                list[i].disable=true;
                }
                else{
                list[i].disable=false;
                }
              }
           }
        }
      }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM