Jay
Jay

Reputation: 3393

One checkbox should be selected from multiple checkboxs with different ng-model

How to validate checkbox with different ng-model??

For e.g:

My HTML looks like:

<form name="myFrm">
  <ul>
      <li><input type="checkbox" ng-model="sunday" />Sunday</li>
      <li><input type="checkbox" ng-model="monday" />Monday</li>
      <li><input type="checkbox" ng-model="tuesday" />Tuesday</li>
      <li><input type="checkbox" ng-model="wednesday" />Wednesday</li>
      <li><input type="checkbox" ng-model="thursday" />Thursday</li>
      <li><input type="checkbox" ng-model="friday" />Friday</li>
      <li><input type="checkbox" ng-model="saturday" />Saturday</li>
  </ul>

  <p ng-if="myFrm.$invalid">Atleast one day should be selected</p>
</form>

from the above code, i want to check atleast 1 checkbox should be selected OR give error message.

I've tried searching, but i found the solution in which has a same ng-model, but i have different ng-model for each checkbox.

How to do that??

DEMO JS FIDDLE

Upvotes: 3

Views: 2847

Answers (1)

Khanh TO
Khanh TO

Reputation: 48982

Try creating custom directives to do custom validation:

//This directive is to update Form validity when any of the elements decorated
// with customRequired is not empty.
app.directive("customRequiredContainer",function(){
  return {
    restrict:"A",
    require:"form",
    controller:function($element,$scope){
      var properties = []; //store the list of properties to check. 

      //customRequired will register the property to be checked.
      this.registerProperty = function(property){
       if (properties.indexOf(property) === -1){
           properties.push(property);

          $scope.$watch(property,function(value){
            if ($element.form){

              //If any of the elements is checked, Form is valid otherwise not valid.
              for (var i=0;i<properties.length;i++){
                if ($scope[properties[i]]){
                  //we should use $setValidity(), 
                  //I don't know why it does not work, check that later.
                  $element.form.$invalid = false;
                  $element.form.$valid = true;
                  return;
                }
              }

              $element.form.$invalid = true;
              $element.form.$valid = false;
            }
          });
        }
      };
    },
    link:function(scope,element,attrs,formController){
      element.form = formController;
    }
  }
});

//This directive is to decorate which element should be checked for validity
app.directive("customRequired",function(){
  return {
    restrict:"A",
    require:"^customRequiredContainer",
    link:function(scope,element,attrs,containerController){
      containerController.registerProperty(attrs.ngModel);
    }
  }
});

HTML:

<form name="myFrm" custom-required-container>
    <ul>
      <li>
        <input type="checkbox" ng-model="sunday" custom-required/>Sunday</li>
      <li>
        <input type="checkbox" ng-model="monday" custom-required/>Monday</li>
      <li>
        <input type="checkbox" ng-model="tuesday" custom-required/>Tuesday</li>
      <li>
        <input type="checkbox" ng-model="wednesday" custom-required/>Wednesday</li>
      <li>
        <input type="checkbox"  ng-model="thursday"  custom-required/>Thursday</li>
      <li>
        <input type="checkbox"  ng-model="friday" custom-required />Friday</li>
      <li>
        <input type="checkbox"  ng-model="saturday" custom-required />Saturday</li>
    </ul>

    <p ng-if="myFrm.$invalid">Atleast one day should be selected</p>
  </form>

DEMO

Or this:

<form name="myFrm">
    <ul>
      <li>
        <input type="checkbox" name="sunday" ng-model="sunday" required/>Sunday</li>
      <li>
        <input type="checkbox" name="monday" ng-model="monday" required />Monday</li>
      <li>
        <input type="checkbox" name="tuesday" ng-model="tuesday" required />Tuesday</li>
      <li>
        <input type="checkbox" name="wednesday" ng-model="wednesday" required />Wednesday</li>
      <li>
        <input type="checkbox" name="thursday" ng-model="thursday" required />Thursday</li>
      <li>
        <input type="checkbox" name="friday" ng-model="friday" required />Friday</li>
      <li>
        <input type="checkbox" name="saturday" ng-model="saturday" required />Saturday</li>
    </ul>

    <p ng-if="myFrm.sunday.$error.required&&myFrm.monday.$error.required
    &&myFrm.tuesday.$error.required&&myFrm.wednesday.$error.required
    &&myFrm.thursday.$error.required&&myFrm.friday.$error.required
    &&myFrm.saturday.$error.required">Atleast one day should be selected</p>
 </form>

DEMO

Explanation:

By giving the inputs names: name="sunday", angular will add the input name as a property of the form: myFrm.sunday. From then, we can check whether the input is selected using its $error.required property.

Or this:

<form name="myFrm">
    <ul>
      <li>
        <input type="checkbox" ng-model="sunday" />Sunday</li>
      <li>
        <input type="checkbox" ng-model="monday" />Monday</li>
      <li>
        <input type="checkbox" ng-model="tuesday" />Tuesday</li>
      <li>
        <input type="checkbox" ng-model="wednesday" />Wednesday</li>
      <li>
        <input type="checkbox"  ng-model="thursday"  />Thursday</li>
      <li>
        <input type="checkbox"  ng-model="friday"  />Friday</li>
      <li>
        <input type="checkbox"  ng-model="saturday"  />Saturday</li>
    </ul>

    <p ng-if="!sunday&&!monday&&!tuesday&&!wednesday&&
    !thursday&&!friday&&!saturday">Atleast one day should be selected</p>
  </form>

DEMO

Upvotes: 5

Related Questions