Search code examples
angularjsvalidationangularjs-directiveangularjs-scopechecklist-model

How to require at least 1 checkbox with checklist-model for AngularJS Form Validation?


I have small form with 2 date input and one checklist which are all checkboxes. I couldn't figure it out how to require any of one checkbox in list for the form validation. If I add ng-required for an checkbox it repeats for all the check boxes. Can anyone know about this how to require the checkbox as required form element. but I don't want to choose all the element for making form valid. So if only one of the form field which are the checkboxes has been selected form must be valid otherwise invalid.

angular.module('frmApp', [
    'ui.bootstrap', 'angularMoment'
  ])
  .controller('Frm Controller', [
    '$scope',
    function($scope) {

      $scope.invDets = $stateParams.details;
      $scope.allowanceObj = {};
      $scope.finCompWithLogo = [];

      $scope.validUntil = new Date();
      $scope.recentDate = new Date();

      // Disable weekend selection
      $scope.disabled = function(date, mode) {
        return (mode === 'day' && (date.getDay() === 0 || date.getDay() === 6));
      };
      $scope.openedPayment = false;
      $scope.openedAllowance = false;
      $scope.openPayment = function($event, elementOpened) {
      	$scope.paymentDueDate = new Date();
        /*$scope.openedPayment = !$scope.openedPayment;*/
        $event.preventDefault();
        $event.stopPropagation();

        $scope[elementOpened] = !$scope[elementOpened];
      };
      $scope.openAllowance = function($event, elementOpened) {
     		$scope.allowanceDueDate = new Date();
        /*$scope.openedAllowance = !$scope.openedAllowance;*/
        $event.preventDefault();
        $event.stopPropagation();

        $scope[elementOpened] = !$scope[elementOpened];
      };

      $scope.dateOptions = {
        'year-format': "'yy'",
        'starting-day': 1,
        'minDate': new Date()
      };
      $scope.doSomething = function (frm) {
$http.post('/someUrl', frm, config).then(successCallback, errorCallback);      alert('Done something!!');
      }
    }
  ]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.1/css/font-awesome.min.css" rel="stylesheet"/>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<div>
  <form name="frm1" novalidate>
    <div class="row">
      <div class="allowance-required-field">
        <div class="box">
          <div class="icon"> <i class="fa fa-calendar"></i> </div>
          <div class="field-title">Payment</div>
          <div class="input-group">
            <input type="text" class="form-control" uib-datepicker-popup="dd-MM-yyyy" ng-click="openPayment($event, 'openedPayment')" ng-model="frm1.PaymentDueDate" show-weeks="false" is-open="openedPayment" datepicker-options="dateOptions" ng-required="true"
            />
            <span class="input-group-btn">
                            <button class="btn btn-default" ng-click="openPayment($event, 'openedPayment')"><i class="fa fa-calendar"></i></button>
                        </span>
          </div>

        </div>
      </div>
      <div class="allowance-required-field">
        <div class="box">
          <div class="icon"> <i class="fa fa-calendar"></i> </div>
          <div class="field-title">Delay</div>
          <div class="input-group">
            <input type="text" class="form-control" uib-datepicker-popup="dd-MM-yyyy" ng-click="openAllowance($event, 'openedAllowance')" ng-model="frm1.AllowanceDueDate" show-weeks="false" is-open="openedAllowance" min-date="recentDate" max-date="frm1.PaymentDueDate"
            datepicker-options="dateOptions" ng-required="true" />
            <span class="input-group-btn">
                            <button class="btn btn-default" ng-click="openAllowance($event, 'openedAllowance')"><i class="fa fa-calendar"></i></button>
                        </span>
          </div>

        </div>
      </div>

      <div class="pick-factoring-companies">
        <div class="box">
          <h2 class="text-center"> Choose One or More </h2>
          
          <div class="text-center">
            <a href="" ng-click="checkAll()" class="btn btn-sm btn-default">Select All</a>
            <a href="" ng-click="uncheckAll()" class="btn btn-sm btn-default">Deselect All</a>
          </div>
          <ul ng-required="true">
            <li ng-repeat="cmp in finCompWithLogo">
              <div ng-if="cmp" class="finance-company">

                <input id="{{'company-'+$index}}" type="checkbox" class="pick-faktoring" checklist-model="frm1.AllowanceCompanies" checklist-value="cmp.Identifier" ng-change="addCompany(cmp.Identifier)">
                <label for="{{'company-'+$index}}">
                  <div class="img"> <img data-toggle="tooltip" data-placement="bottom" src="data:image/{{cmp.Logo[0].Type}};base64,{{cmp.Logo[0].Data}}" title="{{cmp.CompanyName}}"> </div>
                  <div class="title"> {{cmp.CompanyName}} </div>
                </label>
              </div>
            </li>
          </ul>
        </div>
      </div>
    </div>
    <div class="text-center">
      <a href="" ng-click="doSomething(frm1)" ng-disabled="frm1.$invalid" class="btn btn-lg btn-success">Send</a>
    </div>
  </form>

  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>

</div>


Solution

  • SOLVED! I have tried solves my problem.

    <input id="{{'company-'+$index}}" type="checkbox" ng-model="cmp.Selected" ng-click="pushCompanyToArray(cmp)" 
         ng-required="frm1.AllowanceCompanies.length == 0"
         ng-value="cmp.ID" ng-checked="all || cmp.Selected"/>
    

    this solves my question. For anyone who couldn't find the solution this ng-required solved my problem.