0

I'm trying to create a form that will capture input, select and checkbox values and post them to a table. Everything seems to be working fine, with the exception of the checkboxes. What am I doing wrong?

https://jsfiddle.net/mujaji/uvkzmyox/8/

var app = angular.module("myapp", []);
app.controller("ListController", ['$scope', function($scope) {
    $scope.jobtypes = ['accountant', 'janitor', 'ceo', 'receptionist'];
    $scope.hobbies = [{name: "long walks on the beach", id: "1", isChecked: false},{name: "eating cheese", id: "2", isChecked: false},{name: "writing haikus", id: "3", isChecked: false},{name: "looking for bigfoot", id: "4", isChecked: false},{name: "watching police academy", id: "5", isChecked: false}];
$scope.personalDetails = [
    {
        'fname':'Muhammed',
        'lname':'Shanid',
        'jobtype': 'ceo',
        'email':'shanid@shanid.com',
        'active': true,
        'hobbies': [{name: "long walks on the beach", id: "1"},{name: "watching police academy", id: "5"}]
    },
    {
        'fname':'John',
        'lname':'Abraham',
        'jobtype': 'accountant',
        'email':'john@john.com',
        'active': true,
        'hobbies': [{name: "writing haikus", id: "3"},{name: "looking for bigfoot", id: "4"}]
    },
    {
        'fname':'Roy',
        'lname':'Mathew',
        'jobtype': 'janitor',
        'email':'roy@roy.com',
        'active': false,
        'hobbies': [{name: "eating cheese", id: "2"}]
    }];

    $scope.addNew = function(personalDetails){
        $scope.personalDetails.push({ 
            'fname': personalDetails.fname, 
            'lname': personalDetails.lname,
            'email': personalDetails.email,
            'jobtype': personalDetails.jobtype,
        });
        $scope.PD = {};
    };

    $scope.remove = function(){
        var newDataList=[];
        $scope.selectedAll = false;
        angular.forEach($scope.personalDetails, function(selected){
            if(!selected.selected){
                newDataList.push(selected);
            }
        }); 
        $scope.personalDetails = newDataList;
    };

    $scope.checkAll = function () {
        if (!$scope.selectedAll) {
            $scope.selectedAll = true;
        } else {
            $scope.selectedAll = false;
        }
        angular.forEach($scope.personalDetails, function (personalDetails) {
            personalDetails.selected = $scope.selectedAll;
        });
    }; 

}]);

1 Answers1

1

The problem your facing is caused by the fact that hobbies and their checked state is outside the scope of your addNew(personalDetails) function.

Although not ideal for angular, something like this would work:

$scope.addNew = function(personalDetails) {
    //get all checked hobbies
    let selectedHobbies = [];
    $scope.hobbies.forEach(function(hobby) {
        if (hobby.isChecked) selectedHobbies.push(hobby);
    });

        $scope.personalDetails.push({ 
            'fname': personalDetails.fname, 
            'lname': personalDetails.lname,
            'email': personalDetails.email,
            'jobtype': personalDetails.jobtype,
            'hobbies': selectedHobbies
        });
        $scope.PD = {};
    };

EDIT

The answer above is really a pure javascript approach to filtering by selected hobbies. A more 'angular' approach would be to break your filter logic out into its own function so that you're not mixing concerns. For example:

Add the 'filterFilter' dependency to your controller:

app.controller("ListController", ['$scope','filterFilter', 
    function($scope, filterFilter) { ... }

then in your controller, define an array to hold your selected hobbies and add a filter helper to filter by isChecked:

$scope.hobbiesSelection = [];
$scope.selectedHobbies = function selectedHobbies() {
    return filterFilter($scope.hobbies, { selected: true });
};

place a watch on the hobbies object to watch for changes to selected hobbies:

$scope.$watch('hobbies|filter:{isChecked: true}', function (hobbies) {
    $scope.hobbiesSelection = hobbies;
}, true);

and finally, you can update your addNew() method to simply be:

$scope.addNew = function(personalDetails){
    $scope.personalDetails.push({ 
        'fname': personalDetails.fname, 
        'lname': personalDetails.lname,
        'email': personalDetails.email,
        'jobtype': personalDetails.jobtype,
        'hobbies': $scope.selectedHobbies
    });
    $scope.PD = {};
};

So while there is a bit more code (and complexity) there for this example, you are separating the logic from the data a bit better. There is working example here: https://jsfiddle.net/mt0tvkwm/

AJ X.
  • 2,729
  • 1
  • 23
  • 33
  • what do you mean by "not ideal for angular"? Is there a better way to do this outside of your suggestion? Just wondering as I'm new to angular and still learning. thanks axlj – Joseph Sjoblom Nov 19 '16 at 05:05
  • @JosephSjoblom by not ideal, i meant that I wasn't using the angular toolbox to solve the problem. please see my updated answer for details. – AJ X. Nov 19 '16 at 13:03
  • Hi @JosephSjoblom, did this help? Or Should I keep trying? :-) – AJ X. Nov 21 '16 at 22:05
  • This is perfect! Thanks axlj – Joseph Sjoblom Nov 21 '16 at 22:06
  • axlj do you know how to set a default value to my select dropdown? I found an [examples](http://stackoverflow.com/questions/18194255/how-to-have-a-default-option-in-angular-js-select-box), but didn't seem to work. I'm guessing it's because I've already populated my ng-model for the select? – Joseph Sjoblom Nov 22 '16 at 21:02
  • your $scope.hobbies collection has a field: isChecked, you could set this to true when a value should be checked by default? – AJ X. Nov 22 '16 at 21:33
  • sorry, I was referring to the jobtypes array. The select menu is blank by default – Joseph Sjoblom Nov 22 '16 at 21:35