简体   繁体   中英

AngularJS: Populating checkbox list with two JSON arrays and initially checked some items from one array

In my AngularJS application there is a checkbox list. This list represents some interests of a user. The user can select one or more items from the list. HTML

<html>
   <head>
      <title>User Interests</title>
      <script src="../scripts/angular.min.js"></script>
      <script src="../scripts/userinterests.js"></script>
      <script src="//code.jquery.com/jquery-1.12.0.min.js"></script>
      <script src="//code.jquery.com/jquery-migrate-1.2.1.min.js"></script>
   </head>
   <body>
      <div ng-app="userinterests">
         <form ng-submit="submit()" ng-controller="userinterestsCtrl">
            <div ng-repeat="userinterest in userinterests">
               <input type="checkbox" checkbox-group /> <label>{{userinterest.interestKey}}</label>
            </div>
            <input type="submit" id="submit" value="Submit" />
         </form>
      </div>
   </body>
</html>

In my javascript file first I get a list from a backend function, this list contains all the interests. If this backend call success then I call another function to get the already selected items from that user, this returns another list which contains the interests which are already selected by the user. Now I have two lists (list of all the interests & list of already selected interests by the user). Now I want to display a checkbox list with all the interests but I want to check the items which are already selected by the customer.

This is my javascript looks like

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

app.controller('userinterestsCtrl', function($scope, $http) {
// Get full interests list
$http({
    method : 'POST',
    url : './test/userInterests',
    headers : {
        'Content-Type' : 'application/json'
    }
}).success(function(response) {
    console.log('response=>' + response);
    $scope.interests_array = [];
    $scope.userinterests = response;
    console.log($scope.userinterests);

    // Get already selected interests
    $http({
        method : 'POST',
        url : './test/savedInterests',
        headers : {
            'Content-Type' : 'application/json'
        },
        params : {
            user_email : localStorage.getItem("user_email")
        }
    }).success(function(response) {
        console.log('response=>' + response);
        $scope.savedinterests = response;
        console.log(response);
    }).error(function(response, status, headers, config) {
        console.log('failure');
    });

}).error(function(response, status, headers, config) {
    console.log("failure");
});

$scope.submit = function() {
    console.log('Submiting...');
    console.log($scope.interests_array.join(", "));

    var user_email = localStorage.getItem("user_email");
    var preferences = "[" + $scope.interests_array.join(", ") + "]";

    console.log('preferences=>' + preferences);

    $http({
        method : 'POST',
        url : './test/setUserInterests',
        headers : {
            'Content-Type' : 'application/json'
        },
        params : {
            user_email : user_email,
            preferences : preferences
        }
    }).success(function(response) {
        console.log('response=>' + response);

    }).error(function(response, status, headers, config) {
        console.log('failure');
    });
};

}).directive(
    "checkboxGroup",
    function() {
        return {
            restrict : "A",
            link : function(scope, elem, attrs) {
                // Determine initial checked boxes
                if (scope.interests_array.indexOf(scope.userinterest.interestKey) !== -1) {
                    elem[0].checked = true;
                }                   

                // Update array on click
                elem.bind('click', function() {
                    var index = scope.interests_array.indexOf(scope.userinterest.interestKey);
                    // Add if checked
                    if (elem[0].checked) {
                        if (index === -1)
                            scope.interests_array.push(scope.userinterest.interestKey);
                    }
                    // Remove if unchecked
                    else {
                        if (index !== -1)
                            scope.interests_array.splice(index, 1);
                    }
                    // Sort and update DOM display
                    // scope.$apply(scope.array.sort(function(a, b) {
                    // return a - b
                    // }));
                });
            }
        }
    });

sample data

        $scope.userinterests = [{
        "key": "test1",
        "score": 1.0
      }, {
        "key": "test2",
        "score": 1.0
      }, {
        "key": "test3",
        "score": 1.0
      }, {
        "key": "test4",
        "score": 1.0
      }, {
        "key": "test5",
        "score": 1.0
      }, {
        "key": "test6",
        "score": 1.0
      }, {
        "key": "test7",
        "score": 1.0
      }, {
        "key": "test8",
        "score": 1.0
      }, {
        "key": "test9",
        "score": 1.0
      }, {
        "key": "test10",
        "score": 1.0
      }, {
        "key": "test11",
        "score": 1.0
      }];

      var selectedInterests = [{
        "key": "test1",
        "score": 1.0
      }, {
        "key": "test2",
        "score": 1.0
      }, {
        "key": "test3",
        "score": 1.0
      }];

I would be much appreciates if anyone could be so kind enough to help me to achieve this.

Thank You

You could just create an extra property of selected in the userInterests array on runtime like.

userInterests.forEach(function(item){
   savedInterests.forEach(function(savedItem){
      if(savedItem.interestKey === item.interestKey){
         item.selected = true;
      }
   })
})

Then in your template just use

<div ng-app="userinterests">
         <form ng-submit="submit()" ng-controller="userinterestsCtrl">
            <div ng-repeat="userinterest in userinterests">
               <input type="checkbox" checkbox-group ng-model="userinterest.selected" /> <label{{userinterest.interestKey}}</label>
            </div>
            <input type="submit" id="submit" value="Submit" />
         </form>
      </div>

Hope it helps.

Use $filter to search and then add a key in your user_interest array and based on that key, select/unselect a checkbox.

$scope.userinterests = [{
"key": "test1",
"score": 1.0
}, {
"key": "test2",
"score": 1.0
}, {
"key": "test3",
"score": 1.0
}, {
"key": "test4",
"score": 1.0
}, {
"key": "test5",
"score": 1.0
}, {
"key": "test6",
"score": 1.0
}, {
"key": "test7",
"score": 1.0
}, {
"key": "test8",
"score": 1.0
}, {
"key": "test9",
"score": 1.0
}, {
"key": "test10",
"score": 1.0
}, {
"key": "test11",
"score": 1.0
}];

var selectedInterests = [{
"key": "test1",
"score": 1.0
}, {
"key": "test2",
"score": 1.0
}, {
"key": "test3",
"score": 1.0
}];
user_interests.map(function(c,i){
  var found = $filter('filter')(saved_interests, {key: c.key}, true);
  if (found.length) {
      c.active = 1;
      user_interests[i] = c;
  }
});

Check this. its simple and easy

 var app = angular.module('userinterests', []); app.controller('userinterestsCtrl', function($scope, $http) { $scope.userinterests = [{ "key": "test1", "score": 1.0 }, { "key": "test2", "score": 1.0 }, { "key": "test3", "score": 1.0 }, { "key": "test4", "score": 1.0 }, { "key": "test5", "score": 1.0 }, { "key": "test6", "score": 1.0 }, { "key": "test7", "score": 1.0 }, { "key": "test8", "score": 1.0 }, { "key": "test9", "score": 1.0 }, { "key": "test10", "score": 1.0 }, { "key": "test11", "score": 1.0 }]; var selectedInterests = [{ "key": "test1", "score": 1.0 }, { "key": "test2", "score": 1.0 }, { "key": "test3", "score": 1.0 }]; for (var i = 0; i < $scope.userinterests.length; i++) { if (JSON.stringify(selectedInterests).indexOf(JSON.stringify($scope.userinterests[i])) > 0) { $scope.userinterests[i]['active'] = true; } } }); 
 <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.js"></script> <div ng-app="userinterests"> <form ng-submit="submit()" ng-controller="userinterestsCtrl"> <div ng-repeat="userinterest in userinterests"> <input type="checkbox" ng-model='userinterest.active'/> <label>{{userinterest.key}}</label> </div> <input type="submit" id="submit" value="Submit" /> <pre>{{selectedInterests | json}}</pre> </form> </div> 

I would use just one view model object for this, which had an extra 'selected' property, and bind the checkbox to this property using ng-model.

So basically you would create a new object that looked like the response to userinterests, but had a 'selected' boolean property for each interest. You can use Array.map to create this new array.

You could then use ngRepeat to iterate over the new array, creating a checkbox for each entry, which is bound to to the 'selected' property.

When you writing to the server, you can use Array.filter to produce a new array containing only the selected entries, like the response from savedinterests you mention.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM