Search code examples
javascriptarraysangularjscheckboxangular-ngmodel

AngularJS display array based off checkbox selection


I have 4 check boxes, and depending on which one/pair is selected I want a specific array to be displayed on the page. I'm relatively new to angularjs so I'm not sure how to get this to work. So how do I a) check which check box is selected through angular, b) print out the specific array, and c) if "Do Nothing" is selected a message will appear instead of the array. The content should be dynamic so if i choose a different check box the content will change as well. http://codepen.io/MarkBond/pen/gpJWKe?editors=101 the "Simple Form Object" is just to show what that current boolean value is not the array of names that are supposed to appear.

HTML

<html ng-app="myApp">
 .....
 <body ng-controller="FormController">
 <form>
  <div class="checkbox">
    <label>
      <input type="checkbox" name="displayOption" ng-model="formData.displayOption.fiftyMill"/>50 million
    </label>
  </div>
  <div class="checkbox">
    <label>
      <input type="checkbox" name="displayOption" ng-model="formData.displayOption.hundredMill" />100 million
    </label>
  </div>
  <div class="checkbox">
    <label>
      <input type="checkbox" name="displayOption" ng-model="formData.displayOption.statusQuo"/>Status Quo
    </label>
  </div>
  <div class="checkbox">
    <label>
      <input type="checkbox" name="displayOption" ng-model="formData.displayOption.doNothing"/>Do Nothing
    </label>
  </div>
  <div ng-repeat="ActionController as actionCtrl">
    <a>{{ page.name }}</a>
    {{ message }}
  </div>
</form>
</body>
</html>

AngularJS

angular.module('myApp', [])

.controller('FormController', ['$scope' ,function($scope) {

  // Just for outputting data
  $scope.formData = {};

    // Trying to place the boolean value of each checkbox into a variable
    var value1 = '$scope.fiftyMill';
    var value2 = '$scope.hundredMill';
    var value3 = '$scope.statusQuo';
    var value4 = '$scope.doNothing';

    // Checks to see which checkbox is selected then outputting array 
    // associated with selection 
    if (value1 === true || value2 === true) {
        this.page = groupOne
    } else if (value3 === true) {
        this.page = groupTwo
    } else if (value1 === true || value2 === true && value3 === true) {
        this.page = groupThree + groupOne + groupTwo
    }else{
        this.message = 'No Options'
    }

    // Array gtoups
    var groupOne = [
      { name: 'BudgetCharts'},
      { name: 'BudgetComparison'},
      { name: 'EDITBudgetAmounts'}
    ]

    var groupTwo = [
      { name: 'Optimize'},
      { name: 'ReviewAndAdjust'}
    ]

    var groupThree = [
        { name: 'Export'},
        { name: 'Import'},
        { name: 'Construction Program'},
        { name: 'ExportStrategies'}
    ]
}]);

Updated question with how my current code works also with a workable codepen


Solution

  • I'm not sure what would you like to achieve, but i could code your example like this: http://codepen.io/anon/pen/xGNLJe?editors=101

    Explanations:

    (function(angular) {
      "use strict";
    
      angular
        .module('formApp', [])
        .controller('FormController', ['$scope', function($scope) {
          var groupOne = [
            { name: 'BudgetCharts'},
            { name: 'BudgetComparison'},
            { name: 'EDITBudgetAmounts'}
          ];
    
          var groupTwo = [
            { name: 'Optimize'},
            { name: 'ReviewAndAdjust'}
          ];
    
          var groupThree = [
            { name: 'Export'},
            { name: 'Import'},
            { name: 'Construction Program'},
            { name: 'ExportStrategies'}
          ];
    
          $scope.formData = {};
    
          $scope.$watch("formData.displayOption", function(displayOption) {
            if(displayOption) {
              var value1 = displayOption.fiftyMill,
                  value2 = displayOption.hundredMill,
                  value3 = displayOption.statusQuo,
                  value4 = displayOption.doNothing;
    
              $scope.pages = null;
              $scope.message = null;
    
              if (value1 === true || value2 === true) {
                $scope.pages = groupOne;
              } else if (value3 === true) {
                $scope.pages = groupTwo;
              } else if (value1 === true || value2 === true && value3 === true) {
                $scope.pages = groupThree + groupOne + groupTwo;
              } else {
                $scope.message = 'No Options';
              }
            }
          }, true);
        }]);
    })(angular);
    

    So, step by step:

    1. Remove ng-click:

    As you could see, your checkbox's markup now looks like this:

    <input type="checkbox" name="displayOption" ng-model="formData.displayOption.fiftyMill"/>
    

    I removed your ng-click handler and process ng-model updating with $scope.$watch (https://docs.angularjs.org/api/ng/type/$rootScope.Scope) like this:

    $scope.$watch("formData.displayOption", function(displayOption) { ... }, true);

    1. Add $scope.pages and $scope.message variables, interact with it in code and display in view. This is body of your $watch function:

    This fires every time, when "watching" variable (formData.displayOption in your case) changes.

    $scope.pages = null;
    $scope.message = null;
    
    if (value1 === true || value2 === true) {
        $scope.pages = groupOne;
    } else if (value3 === true) {
        $scope.pages = groupTwo;
    } else if (value1 === true || value2 === true && value3 === true) {
        //
        // Algorithm never goes here, because:
        // value1 === true || value2 === true, always goes to first if block
        // value3 === true, it goes to second if block
        // there aren't any other options to go here 
        //
        $scope.pages = groupThree + groupOne + groupTwo;
        //
        // groupThree, groupOne, groupTwo are arrays. If you plus
        // arrays in javascript like this: 
        // [1,2] + [3,4,5] you will get string = "1,23,4,5"
        //
        // if you want to have [1,2,3,4,5] array as result of adding arrays,
        // you have to use concatenation like this:[1,2].concat([3,4,5])
        //
        // In your case:
        // $scope.pages = groupThree.concat(groupOne.concat(groupTwo));
    } else {
        $scope.message = 'No Options';
    }
    

    and then display in view (as you can see, you assign into $scope.pages an array, so you could iterate over it with ng-repeat):

    <h3>Pages</h3>
    <div ng-repeat="page in pages">
      {{ page.name }}
    </div>  
    
    <div>{{ message }}</div>
    

    P.S. Look at comments in my code, you could have mistakes in places i've commented.