Trailing closely the Hello world, the Echo, and the simple calculator examples, creating a TODO list is one of the rite of passage entering the world of whatever language or environment. Let's see how to implement a TODO using AngularJS.
Simple TODO list
After loading angular.min.js
we create an Angular JS module called todoApp
and
a controller called todoController
. Inside the controller we set up an empty array
called tasks
that will hold the todo list.
We make it an attribute of the current $scope
in order to make it accessible form the HTML.
We also declare a function called add
(also an attribute of the $scope
) that takes the
value of title
(we'll later see this is the name of the input
box), and appends it
to the list of tasks using push
. That's all the JavaScript code we need for a simple TODO list.
In the HTML part we have a div
element that defined the area of the
AngularJS Application ng-app
and the Angular JS controller ng-controller
.
Inside the controller in the HTML we have two parts. The first part is an input
element
connected to the $scope.title
attribute using ng-model
and a button that uses
ng-click
to launch the $scope.add
method when the button is clicked.
The second part uses the ng-repeat
directive to iterate over the elements of the $scope.tasks
array and display them one-by-one as list items.
<script src="angular.min.js"></script>
<script>
angular.module('todoApp', [])
.controller('todoController', function($scope){
$scope.tasks = [];
$scope.add = function() {
$scope.tasks.push($scope.title);
}
})
</script>
<div ng-app="todoApp" ng-controller="todoController">
<input ng-model="title"><button ng-click="add()">Add</button>
<ul>
<li ng-repeat="t in tasks">{{ t }}</li>
</ul>
</div>
Submit input box on pressing ENTER
It is a bit cumbersome that for every additional item we need to click on the button.
It would be much better if we could just press ENTER. In order to do that we had to wrap
the input
element in a form
and in the form add an ng-submit
directive calling the $scope.add
function. At the same time, in order to eliminate
duplicate calling of the $scope.add
function.
<form ng-submit="add()">
<input ng-model="title"><button>Add</button>
</form>
Duplicate values in ng-repeat
If yo have tried the above example, you might have noticed that adding the same element twice
will crash the application. The reason is that by default the ng-repeat
directive
assumes unique values in an array. I am not sure if having the same value in a TODO list
is actually desirable, but for now I'd like to be able to allow the user to enter the same value
twice. To do so we can tell ng-repeat
to use the $index
of the array for tracking
values like this:
<li ng-repeat="t in tasks track by $index">{{ t }}</li>
Deleting an element from the TODO list
While for most of us the reality is that we have an ever growing TODO list, but sometime we get lucky and manage to finish an item. (Or maybe it just gets cancelled.) We would like to have a way to remove an element. For that we are going to add a button next to each item, and clicking on that button will remove the specific element from the array of tasks.
Adding the button is simple:
<button ng-click="delete()">x</button>
The appropriate delete
function made me scratch my head a bit, but finally I
got it:
$scope.delete = function() {
$scope.tasks.splice(this.$index, 1);
}
When running the delete
function this
contains an attribute called $index
that
seems to indicated the index in the current list. We can use that to locate the element in the
tasks
array. Using the plain JavaScript `splice function we remove one element from
the array that immediately updates the list displayed on the HTML page.
<script src="angular.min.js"></script>
<script>
angular.module('todoApp', [])
.controller('todoController', function($scope) {
$scope.tasks = [];
$scope.add = function() {
$scope.tasks.push($scope.title);
}
$scope.delete = function() {
$scope.tasks.splice(this.$index, 1);
}
})
</script>
<div ng-app="todoApp" ng-controller="todoController">
<form ng-submit="add()">
<input ng-model="title"><button>Add</button>
</form>
<ul>
<li ng-repeat="t in tasks track by $index">{{ t }} <button ng-click="delete()">x</button></li>
</ul>
</div>