0

Hi i have form in angularjs and that form have many checkboxes on clicking first checkbox i,e check All i want to checked the all checkboxes . how i can i do that with angular for each field loop here is my sample code I am trying in code snipt.

vm.asas = function() {
  angular.forEach($scope.quizSettingsForm, function(field) {
    console.log(field);
    angular.forEach(field, function(errorField) {
      errorField.$setTouched();
    });
  });
  console.log(vm.QuizSettings);
};
<form name="quizSettingsForm" novalidate>
  <div class="panel panel-default">
    <div class="panel-heading">
      QUIZ SETTINGS
    </div>
    <div class="panel-body">
      <ul>
        <li>
          <div class="checkbox">
            <input type="checkbox" id="checkall" ng-model="vm.checkAll" ng-click="vm.asas()" />
            <label for="checkall">Check /Uncheck ALL</label>
          </div>
        </li>
        <li>
          <div class="checkbox">
            <input type="checkbox" ng-model="vm.QuizSettings.IsOpened" id="Cohort" />
            <label for="Cohort">Have a open Quiz</label>
          </div>
        </li>
        <li>
          <div class="checkbox">
            <input type="checkbox" ng-model="vm.QuizSettings.IsMandatory" id="mandatory" />
            <label for="mandatory">Is Mandatory</label>
          </div>
        </li>
        <li>
          <div class="checkbox counterdiv">
            <input type="checkbox" ng-model="vm.QuizSettings.ShouldExpireAfterExpiry" id="invitation" />
            <label for="invitation">  <p>The quiz will expire <input type="number" ng-model="vm.QuizSettings.Expiry" ng-min="1" name="expiry"> days after invitation</p></label>
            <span class="validation-message" ng-show=" vm.QuizSettings.ShouldExpireAfterExpiry && quizSettingsForm.expiry.$touched && quizSettingsForm.expiry.$error.min"><i class="fa fa-warning"></i> The minimum value is 1.</span>
          </div>
        </li>
        <li>
          <div class="checkbox">
            <input type="checkbox" ng-model="vm.QuizSettings.AllowRetakes" id="dontallow" />
            <label for="dontallow">Allow Retake and dont allow more than </label>
            <input type="number" ng-model="vm.QuizSettings.AlllowMoreThen" ng-min="1" name="dontallow"><span style="color: #696969;font-size: 18px;font-weight: normal;"> Retakes </span>
            <span class="validation-message" ng-show="quizSettingsForm.dontallow.$touched && quizSettingsForm.dontallow.$error.min"><i class="fa fa-warning"></i> The minimum value is 1.</span>
          </div>
        </li>
      </ul>
    </div>
  </div>
</form>

2 Answers 2

2

One Approach (if checkbox properties are on same object with other properties)

You could (not necessarily should) store property names in an array, and then you could use a forEach loop to set the property itself on the vm.quizSettings object:

function selectAll(){

  var myArray = [
    "IsOpened", 
    "IsMandatory", 
    "ShouldExpireAfterExpiry"
  ];

  angular.forEach(myArray, function(propName){
    vm.QuizSettings[propName] = true;
  });
}

Much Better (if checkbox properties are alone on same object)

It would be much better if you could avoid storing property names as strings. If all of your checkbox boolean properties to update were alone on it's own object, then it becomes much cleaner:

function selectAll(){
  var myArray = Object.keys(vm.QuizSettings);
  angular.forEach(myArray, function(propName){
    vm.QuizSettings[propName] = true;
  });
}

Better Still (simply decorate the checkboxes that this behavior should apply to)

Create a custom directive selectAllListener that listens to a "SelectAll" event and updates ngModel value to true when that event is raised.

function thisDirective() {
  return {
    restrict: 'A',
    require: 'ngModel',
    link: function(scope, el, attr, ngModel){
      scope.$on("SelectAll", function(){
        ngModel.$setViewValue(true);
        ngModel.$render();  
      });
    }
  }
}

Add the select-all-listener decorator directive to your checkboxes:

<li>
  <div class="checkbox" >
    <input select-all-listener type="checkbox" id="checkall" ng-model="vm.checkAll" ng-click="vm.asas()"/>
    <label for="checkall" >Check /Uncheck ALL</label>
  </div> 
</li>

Raise the event from within your controller:

function selectAll(){
  $rootScope.$broadcast("SelectAll");
}
Sign up to request clarification or add additional context in comments.

8 Comments

can i do it with form fields as in my question code
and what if there is also some obj in vm.QuizSettings beside property
@Asad That was the assumption with the first answer, to store property names in an array so that you don't overwrite other properties/objects on your vm.QuizSettings object.
well thats cumbersome i think can i do it with angular.foreach field loop ?
@Asad you can use angular.forEach instead, which works the same way, just a different syntax. I've updated the answer to use angular.forEach() instead.
|
0

Build an object for your form where isChecked key refers to checkbox value and name refers the label and value refers the model or value of input.

$scope.FormAttributeList = [
    {
        id: 1,
        name: "xyz",
        value: "xyz",
        isChecked: false
    },
    {
        id: 2,
        name: "xyz",
        value: "xyz",
        isChecked: false
    },
    {
        id: 3,
        name: "xyz",
        value: "xyz",
        isChecked: false
    },
    {
        id: 4,
        name: "xyz",
        value: "xyz",
        isChecked: false
    }
]

your code will be like 

<div class="panel-body">
    <ul>
        <li>
           <div class="checkbox" >
                <input type="checkbox" id="checkall" ng-model="vm.checkAll" ng-click="selectAll(vm.checkAll,FormAttributeList)"/>
                <label for="checkall" >Check /Uncheck ALL</label>
            </div> 
        </li>
        <li ng-repeat="item in FormAttributeList">
            <div class="checkbox">
                <input type="checkbox" ng-model="item.value" id="item.id" />
                <label for="Cohort" >{{item.name}}</label>
            </div>
        </li>
</div>

Now create a function like 

$scope.selectAll = function(checkAll,List) {
    angular.forEach(list,function(value,key){
        value.isChecked = checkAll;
    });
};

This is the best way to do what you want it'll remove your unnecessary code.

1 Comment

This works until you get down to ShouldExpireAfterExpiry, where there are other fields e.g. a textbox bound to vm.QuizSettings.AlllowMoreThen with it's own validation criteria and message.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.