Philo
Philo

Reputation: 1989

AngularJS adding a new item and removing an existing item from a list

(1) I am trying to add a new user to a list of items (userList). The functionality works, but there is an issue. I made the list 'selectable' aka.. when a user clicks on an item on the list the textboxes in my html5 code gets populated w/ values from the selected item in the list. This allows the user to edit the individual properties from the item. Right underneath the group of textboxes is my 'add new user' button..... When the app first runs, the textboxes are empty and I fill them w/ appropriate text and click the add button and the new user is appended to the list. However the issues is, when I have already selected an item, edited it... then the textboxes are still populated w/ the item values... now if I click add new user... a new user is added... but now I have duplicate users in my list.. which is fine because I can always edit one of them... However.... it looks like both the new and the old user are now somehow linked... if I edit one of them, the values in the other also change... (I hope this makes sense). I feel that because the new user was created via the selected record of the old user, somehow their indexes are related....can't seem to figure out how to create a new user without having the old user connected to it.

(2) Deleting a user works fine, but except, the user deleted is always from the bottom of the list. I want to be able to select any item in the list and delete that specific item. I tried using something like:-

$scope.userList.splice($scope.userList.indexOf(currentUser), 1);

but to no avail.

My Javascript:-

<script type="text/javascript">
    function UserController($scope) {
        $scope.userList = [
           { Name: "John Doe1", Title: "xxxx", Company: "yyyy", Place: "zzzz" },
           { Name: "John Doe2", Title: "xxxx", Company: "yyyy", Place: "zzzz" },
           { Name: "John Doe3", Title: "xxxx", Company: "yyyy", Place: "zzzz" },
           { Name: "John Doe4", Title: "xxxx", Company: "yyyy", Place: "zzzz" }
        ];


        $scope.selectUser = function (user) {
            $scope.currentUser = user;
        }

        $scope.addNew = function (currentUser) {
            $scope.userList.push(currentUser);
            $scope.currentUser = {}; //clear out Employee object
        }

        $scope.removeItem = function (currentUser) {
           // $scope.userList.pop(currentUser);
            $scope.userList.splice($scope.userList.indexOf(currentUser), 1);
            $scope.currentUser = {}; //clear out Employee object
        }
    }
</script>

My HTML:-

<div class="row">
        <div style="margin-top: 40px"></div>
        <div data-ng-app="" data-ng-controller="UserController">
            <b>Employee List</b><br />
            <br />
            <ul>
                <li data-ng-repeat="user in userList">

                    <a data-ng-click="selectUser(user)">{{user.Name}} | {{user.Title}} | {{user.Company}} | {{user.Place}}. </a>

                </li>
            </ul>
            <hr>
            <div style="margin-top: 40px"></div>
            <b>Selected Employee</b><br />
            <br />
            <div style="border:dotted 1px grey; padding:20px 0 20px 0; width:40%;">
            <div class="row" style="margin-left: 30px">
                <div style="display: inline-block;">
                    Name: 
                </div>
                <div style="display: inline-block; margin-left: 35px;">
                    <input type="text" data-ng-model="currentUser.Name">
                </div>
            </div>
            <div style="margin-top: 20px"></div>
            <div class="row" style="margin-left: 30px">
                <div style="display: inline-block;">
                    Title: 
                </div>
                <div style="display: inline-block; margin-left: 45px;">
                    <input type="text" data-ng-model="currentUser.Title">
                </div>
            </div>
            <div style="margin-top: 20px"></div>
            <div class="row" style="margin-left: 30px">
                <div style="display: inline-block;">
                    Company: 
                </div>
                <div style="display: inline-block; margin-left: 10px;">
                    <input type="text" data-ng-model="currentUser.Company">
                </div>
            </div>
            <div style="margin-top: 20px"></div>
            <div class="row" style="margin-left: 30px">
                <div style="display: inline-block;">
                    Place:
                </div>
                <div style="display: inline-block; margin-left: 35px;">
                    <input type="text" data-ng-model="currentUser.Place">
                </div>
            </div>
            </div>
            <div>
                <div style="margin: 2% 0 0 8%; display:inline-block">
                    <button data-ng-click="addNew(currentUser)" class="btn btn-primary" type="button">Add New Employee</button>
                </div>
                <div style="margin: 2% 0 0 1%; display:inline-block">
                    <button data-ng-click="removeItem(currentUser)" class="btn btn-primary" type="button">Delete Employee</button>
                </div>
            </div>
            <hr>
            <div style="margin-top: 40px"></div>
            <b>Employee Details:</b><br />
            <br />
            {{currentUser.Name}} is a {{currentUser.Title}} at {{currentUser.Company}}. He currently lives in {{currentUser.Place}}. 
        </div>
    </div>

* EDIT * I solved the delete user issue as:-

 $scope.removeItem = function (currentUser) {
                if ($scope.userList.indexOf(currentUser) >= 0) {
                    $scope.userList.splice($scope.userList.indexOf(currentUser), 1);
                    $scope.currentUser = {}; //clear out Employee object
                }
            }

and thanks to the suggestion, the add new user issue has also been resolved.

Upvotes: 0

Views: 4186

Answers (1)

cdhowie
cdhowie

Reputation: 169018

You have two issues. In $scope.addNew():

$scope.userList.push(currentUser);

This line pushes a reference to the same object you are currently editing. This is why the users appear linked, because you have the same object in the list twice. You instead need to copy the properties of the object onto a new object, which you can do in this case with angular.extend():

$scope.userList.push(angular.extend({}, currentUser));

You might instead consider having the "add new" button just add a blank user to the list and select it for editing:

$scope.addNew = function () {
    $scope.userList.push($scope.currentUser = {});
};

In $scope.removeItem(), you use the pop() method of the array to try to remove a specific item, but pop() removes the last item and doesn't actually accept any arguments:

$scope.userList.pop(currentUser);

You could iterate the list to remove a specific object:

var i;
for (i = 0; i < $scope.userList.length; ++i) {
    if ($scope.userList[i] === currentUser) {
        $scope.userList.splice(i, 1);
        break;
    }
}

Or you could use indexOf() but test that the return value is not equal to -1, or the splice() call will remove the last element from the list.

Upvotes: 2

Related Questions