title: How do I conditionally uncheck a checkbox in Angular ng-grid? (Revert/undo cell value onChange or onClick.)
body: <p>I have been trying to figure out how to programmatically "uncheck" a checkbox on an ng-grid for days, and I am beginning to lose my mind. It can't possibly be this hard to solve this problem.
  I have tried everything that I can possibly think of, and I have tried every example that I have been able to find on the internet. Please, someone have mercy on me.</p>
  
  <p>The grids display fine, but I cannot figure out how to get uncheck the checkbox when this condition occurs: "if(!daysvalidfor || daysvalidfor &lt; 0 || daysvalidfor > 100000)". The situation should occur when the "daysvalidfor" field is empty when someone checks the checkbox for that given row; and when this occurs, I want to "undo" the checkbox to make it empty again. That's it! All I want to do is conditionally uncheck the checkbox. Simple, right?</p>
  
  <p>Here are the respective grids in the HTML:</p>
  
  <pre><code>                &lt;div id="trainingGrid" 
                      class="gridStyle" 
                      ng-grid="trainingGridOptions" 
                      class="ngGrid" 
                      ng-show="isLocationSelected &amp;&amp; !isMeetingSelected()" 
                          &gt;
                  &lt;/div&gt;
                  &lt;div id="meetingGrid" 
                          class="gridStyle" 
                          ng-grid="meetingGridOptions" 
                          class="ngGrid" 
                          ng-show="isLocationSelected &amp;&amp; !isTrainingSelected()" 
                              &gt;
                  &lt;/div&gt;
  </code></pre>
  
  <p>You will see code that probably does not make sense or was commented out while I was exhaustively trying to solve this problem.</p>
  
  <pre><code>managementApp.controller('managementController', 
      function ($scope, $timeout, $http) {
          $scope.locationName;
          $scope.myLocation;
          $scope.locations = {};
          $scope.trainingTemplates = {};
          $scope.meetingTemplates = {};
          $scope.getLocations = function(homeId) {
              var data = contentClient.GetLocations(homeId);
              $scope.locations = data;
              return data;
              //locations = data;
          };  
          $scope.selectedGrid = 'training'; // this is the default value of the grid to display.
          $scope.setSelectedGrid = function(selectedGrid){ $scope.selectedGrid = selectedGrid}
          $scope.isTrainingSelected = function() {
              if($scope.selectedGrid == "training") 
              {
                  return true;
              }
          };
  
  
          $scope.isLocationSelected = false;
          $scope.removeLocalTemplate = function(locationTemplateId, documentType){
  
              var result = contentClient.RemoveLocationTemplate(locationTemplateId, documentType);
  
          }
          $scope.getLocationTemplates = function(type) {
              var locationId = $scope.myLocation.Id;
              if(locationId)
              {
                  var data = {};
  
                  if(type == "training"){
                      data = contentClient.GetLocationTrainingTemplates(locationId);
                      $scope.trainingTemplates = data;
                  }
  
                  $("#trainingGrid").height(20*$scope.trainingTemplates.length);
                  return data;
              }
              //locations = data;
          };
          $scope.toggleTraining = function(templateId, name, masterTemplateId, isLocalTemplate, daysvalidforStr, row){
              var oldCheckboxValue = $scope.rowHolder;
              var daysvalidfor = parseInt(daysvalidforStr);
              //$scope.master = false; // This line actually updates all of the values!!!
              var tempData = angular.copy($scope.trainingGridOptions.$gridScope.trainingTemplates);
              tempData.forEach(function(value, key){
                  if (key &gt; 50){
                  tempData[key].isLocalTemplate = true;
                  //value.isLocalTemplate = true;
                  }
                  if (key &lt; 50){
                  tempData[key].isLocalTemplate = false;
                  //value.isLocalTemplate = true;
                  }
              });
              $scope.trainingGridOptions.$gridScope.trainingTemplates = tempData;
  
              /*
              $scope.trainingGridOptions.$gridScope.renderedRows[6].entity.isLocalTemplate = false;
                          $scope.trainingGridOptions.$gridScope.renderedRows[7].entity.isLocalTemplate = true;
                              $scope.trainingGridOptions.$gridScope.renderedRows[8].entity.isLocalTemplate = true;
              */
              //alert(templateId + name + masterTemplateId + isLocalTemplate + daysvalidfor);
              // if $scope.rowHolder.isLocalTemplate == true, then construct the node.
              // if $scope.rowHolder.isLocalTemplate == false, then destroy the node.
              if ($scope.rowHolder.isLocalTemplate == true){ // means we are constructing
                  if(!daysvalidfor || daysvalidfor &lt; 0 || daysvalidfor &gt; 100000){
                      alert("The value of daysvalidfor must be a valid number between 0 and 100000 for " + name);
                      //$scope.rowHolder.isLocalTemplate = isLocalTemplate;
                      //$scope.row.entity.daysvalidfor = isLocalTemplate;
                      //$scope.row = row;
                      //$scope.rowHolder.isLocalTemplate = false; // $scope.rowHolder is undefined unless we provide row in the method parameters above.
                      //$scope.row.entity.isLocalTemplate = false; // $scope.row is undefined.
                      //row.entity.isLocalTemplate = false;
                      //$scope.update($scope.rowHolder.isLocalTemplate);
                      //var isChecked = document.getElementById("isLocalCheckbox").checked;
                      // Note: The isChecked variable value should match the value of $scope.rowHolder.isLocalTemplate.
                      //document.getElementById("isLocalCheckbox").checked = false;
                      // we want to uncheck it here because there was not a valid daysvalidfor value.
                      $scope.trainingGridOptions.$gridScope.row.entity.isLocalTemplate = false;
  
                      $scope.trainingTemplates = $scope.getLocationTemplates("training");
                      $scope.$apply; // does nothing.
                      // reload the nodes to reset the grid checkbox due to invalid argument.
                  }
                  else{ // otherwise, construct the node.
                      var locationId = $scope.myLocation.Id;
                      var destinationContainerId = 1577;
                      var result = contentClient.constructLocalTraining(locationId, templateId, name, masterTemplateId, isLocalTemplate, destinationContainerId, daysvalidfor);
  
                  }
  
              }
              if($scope.rowHolder.isLocalTemplate == false) { // means we unchecked the box to remove the node.
                  // note: templateId and masterTemplateId should not match in this case.
                  if(templateId != masterTemplateId){
  
                      var result = $scope.removeLocalTemplate(templateId, "localTrainingTemplate");
  
                      $scope.getLocationTemplates("training"); // refresh nodes. It should omit the existing one.
                  }
                   else{
                       alert("Impossible case will never evaluate to true. Check $scope.toggleTraining.");
                   }
              }
          }
  
          $scope.invalidCheckbox = false;
  
          //$scope.master = true;
          $scope.selectLocation = function(location){
                  $scope.myLocation = location;
                  $scope.isLocationSelected = true;   
          };
          var template = '&lt;input class="ngSelectionHeader" name="localCheckbox" id="isLocalCheckbox" type="checkbox" ng-checked="master" ng-click="cacheRow(row.entity, row); toggleTraining(row.entity.Id, row.entity.Name, row.entity.masterTrainingId, row.entity.isLocalTemplate, row.entity.daysvalidfor, row)" /&gt;';
          var newTemplate = '&lt;div class="ngSelectionCell"&gt;&lt;input tabindex="-1" class="ngSelectionCheckbox" type="checkbox"  ng-model="row.entity.isLocalTemplate" ng-checked="row.entity.isLocalTemplate" ng-change="toggleTraining(row.entity.Id, row.entity.Name, row.entity.masterTrainingId, row.entity.isLocalTemplate, row.entity.daysvalidfor, row)" /&gt;&lt;/div&gt;'
          /*
  var template = '&lt;input class="ngSelectionHeader" name="localCheckbox" id="isLocalCheckbox" type="checkbox" ng-model="row.entity.isLocalTemplate" ng-change="cacheRow(row.entity, row); toggleTraining(row.entity.Id, row.entity.Name, row.entity.masterTrainingId, row.entity.isLocalTemplate, row.entity.daysvalidfor, row)" /&gt;';
          var newTemplate = '&lt;div class="ngSelectionCell"&gt;&lt;input tabindex="-1" class="ngSelectionCheckbox" type="checkbox" ng-checked="row.selected" /&gt;&lt;/div&gt;'*/
          $scope.trainingGridOptions = {
              data: 'trainingTemplates',
              enableCellEdit: true,
              //enableCellSelection: false,
              enableRowSelection: false,
              columnDefs: [
                {field: 'Id', displayName: 'Id'},
                {field: 'Name', displayName: 'Name'},
                {field: 'masterTrainingId', displayName: 'masterTrainingId'},
               // {field: 'isLocalTemplate', displayName: 'isLocalTemplate'},
                {field: 'isLocalTemplate', 
                     displayName: 'isLocalTemplate', 
                     enableCellEditOnFocus: true,
                     cellTemplate: template},
                {field: 'daysvalidfor', 
                      displayName: 'daysvalidfor',
                      enableCellEditOnFocus: true,
                      cellTemplate: '&lt;span ng-cell-text&gt;&lt;input type="number" min="0" max="100000" ng-model="row.entity.daysvalidfor" ng-focus="cacheRow(row.entity)" ng-blur="updateEntity(row)" &gt;&lt;/span&gt;'
                  }
              ]    
            };
          // see http://technpol.wordpress.com/2013/12/06/editable-nggrid-with-both-dropdowns-and-selects/
                  $scope.cacheRow = function(startValue, row) {
            $scope.rowHolder = {};
          $scope.row = row;
            angular.copy(startValue, $scope.rowHolder);
              $scope.rowHolder.isLocalTemplate = !row.entity.isLocalTemplate;
          };
  
          $scope.updateEntity = function(row){
              //$scope.gridColumn = column;
              //$scope.gridRow = row; // this wasn't commented out before.
              //$scope.gridCell = cellValue;
              //Code to prevent multiple ngBlur events
              //http://technpol.wordpress.com/2013/12/06/editable-nggrid-with-both-dropdowns-and-selects/
              /*if(!$scope.save) {
                  $scope.save = { promise: null, pending: false, row: null };
              }
                $scope.save.row = row.rowIndex;
                if(!$scope.save.pending) {
                  $scope.save.pending = true;
                  $scope.save.promise = $timeout(function(){
                    // $scope.list[$scope.save.row].$update();
                    alert("We will save your record to the server, we're updating row: " 
                      + $scope.save.row + " to have: " 
                      + $scope.list[$scope.save.row].isLocalTemplate );
                    $scope.save.pending = false; 
                  }, 500);
                }*/ 
              };
  
  
  
  
  
      }
  );
  </code></pre>