ng-required changing checkbox from false to undefined

I’ve been banging my head for a while on this one.

I have a checkbox typed input using ng-model, ng-required, and ng-change

When I uncheck a checkbox I expect the ng-model to be set to false, but it is actually being set to undefined

Also when the ng-required expression toggles; the ng-model also bounces between undefined and false which in turn causes ng-change to trigger.

My actual ng-change code executes some code I do not want to run multiple times.

The simple snippet below shows what I’m running into. I threw a text input into the example to see if it did the same thing. It appears to do the same thing when a user enters a string then deletes it…

This question is not about text inputs…I’m mostly surprised that a false value is not a valid checkbox value when ng-required is true.

var app = angular.module('example', []);

app.controller('controller',['$scope', function($scope){
  $scope.inputModel = {
    isSelected: undefined,
    textInput: undefined
  };
	
	$scope.onChangeCounter = 0;

	$scope.requiredModel = true;

  $scope.resolveCheckboxInput = function() {
    if (typeof $scope.inputModel.isSelected === "undefined") {
      return "I am undefined"
    }
    return "I am " + $scope.inputModel.isSelected
  };

  $scope.resolveTextInput = function() {
    if (typeof $scope.inputModel.textInput === "undefined") {
      return "I am undefined"
    }
    return "I am " + $scope.inputModel.textInput
  };
  
  $scope.onChangeCallback = function() {
  	$scope.onChangeCounter++;
  };
  
  $scope.isRequired = function() {
  	return $scope.requiredModel;
  };
}]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>


<div ng-app="example">
    <ul>
    <li> Set Checkbox Input to TRUE</li>
    <li> Set Checkbox Input to FALSE</li>
    <li> Toggle ng-required</li>
    <li> Checkbox Input is cleary affected</li>
    </ul>
    <div ng-controller="controller">
      <label>
        <input type="checkbox"
          ng-required="isRequired()"
          ng-change="onChangeCallback()"
          ng-model='inputModel.isSelected'  />
      Checkbox Input
      </label>
      <br><br>
      <div>
        <b>Checkbox Input:</b> {{resolveCheckboxInput()}}
      </div>
      <br><br>
      <label>
        <input type="text"
          ng-required="isRequired()"
          ng-model='inputModel.textInput'  />
      Text Input
      </label>
      <br><br>
      <div>
        <b>Text Input:</b> {{resolveTextInput()}}
      </div>
      <br><br>
        <label>
          <input type="checkbox"
              ng-model='requiredModel' />
          ng-required
        </label>
      <br><br>
      <div>
        <b>Checkbox Input ng-change Counter:</b> {{onChangeCounter}}
      </div>
    </div>
</div>

Here is Solutions:

We have many solutions to this problem, But we recommend you to use the first solution because it is tested & true solution that will 100% work for you.

Solution 1

Credit goes to this SO question/answer: Checkbox input undefined when unchecked – AngularJS

You need to add ng-model-options.

<input type="checkbox"
    ng-required="isRequired()"
    ng-change="onChangeCallback()"
    ng-model='inputModel.isSelected'
    ng-model-options="{ allowInvalid: true }" />

I’d usually mark this as duplicate but the answer in the link wasn’t accepted, so it may not be apparent that this works.

Note: Use and implement solution 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply