Reputation: 2668
I tried to achieve a simple feature with AngularJS as below. In item list, when user clicks an item and click the Remove button then the item will be removed.
html:
<div ng-app="app" ng-controller="MainController">
<div>
<select ng-options="item.name for item in items" ng-model="currentItem" size="5" style="width: 200px"></select>
</div>
<button ng-click="removeItem()">Remove</button>
</div>
and script is like below:
angular.module('app', [])
.controller('MainController', function($scope) {
$scope.items = [{
name: 'item1'
}, {
name: 'item2'
}, {
name: 'item3'
}];
$scope.currentItem = $scope.items[0];
$scope.removeItem = function() {
var index = $scope.items.indexOf($scope.currentItem);
$scope.items.splice(index, 1);
};
});
The problem is when I tried to remove an item (i.e. item2), the list always shows an empty item in the first position. When I click 'item1' or 'item3', the empty item disappears.
I know that this is caused by ng-model="currentItem"
in html. The item that currentItem points to get removed, currentItem points to null. So I changed the function removeItem as below to solve this issue.
$scope.removeItem = function() {
var index = $scope.items.indexOf($scope.currentItem);
$scope.items.splice(index, 1);
/* PART 1 begin */
if ($scope.items.length === 0) {
$scope.currentItem = null;
} else {
if (index >= 0 && index <= $scope.items.length - 1) {
$scope.currentItem = $scope.items[index];
} else {
$scope.currentItem = $scope.items[$scope.items.length - 1];
}
}
/* PART 1 end */
};
I would like to know whether there is any simple way (like a directive) in AngularJS to do the action in PART 1 automatically.
Upvotes: 3
Views: 101
Reputation: 20741
There is simple way in which you can prevent that is just include
<option value="" ng-show="false"></option>
in select like as shown below
<select ng-options="item as item.name for item in items" ng-model="currentItem" size="5" style="width: 200px">
<option value="" ng-show="false"></option>
</select>
UPDATE 1
I have resolved the issue of not highlighting the last item, Take a look the working demo
$scope.removeItem = function () {
var index = $scope.items.indexOf($scope.currentItem);
$scope.items.splice(index, 1);
index === $scope.items.length ? $scope.currentItem = $scope.items[index - 1] : $scope.currentItem = $scope.items[index];
};
Upvotes: 4